Arc Forumnew | comments | leaders | submit | sjs's commentslogin
2 points by sjs 6308 days ago | link | parent | on: macro / function question

Arbitrary number of arguments:

  (mac drill (lst . xs)
    (if (no xs)       `,lst
        (no (cdr xs)) `(,lst ,(car xs))
        `((drill ,lst ,@(rev (cdr (rev xs)))) ,(last xs))))

-----


These are interesting ideas. I really like the idea of using @ as an analog to Ruby's splat. After thinking about it for a few minutes I think I like (string:@map ...) too, though I think it's starting to look like line noise.

If you compose a function with a value what does that mean? Something like ((fn (y) (prn y) y) x)? In the example you gave I would still expect to wrap prn:x is parens to execute the resulting procedure.

-----

1 point by drcode 6307 days ago | link

you are correct about the parens on prn:x... I thought I had a clever trick from making them unecessary, but it didn't pan out when I sat down to work out the necessary transformations... creating decent language primitives is hard...

...your "line noise" comment also is a good point...

-----

1 point by sjs 6307 days ago | link

This stuff is hard. I looked into implementing general splicing functionality but it is not trivial. Reading @bar and translating it to (splice 'bar) is easy enough, but then you would have to examine the arguments of every sexp before evaluating it to handle the splice. I guess it's not particularly difficult but it would likely be a performance hit. Perhaps there is a clever trick to do general splicing.

-----

1 point by almkglor 6305 days ago | link

Probably a similar trick to `, . Need more hints?

-----

1 point by bogomipz 6307 days ago | link

prn:x should mean [prn (x _)] because x is no different from prn, and may very well be a function. Unless you can statically know the value of x, but statical analysis of variable content does not sound very lispy to me. While it's ok for optimization it is not ok for semantics!

-----

1 point by sjs 6308 days ago | link | parent | on: Lazy structures?

There is force/delay as demonstrated in SICP and On Lisp, or lazy call-by-name thunks. These are pretty rudimentary but they work.

http://swiss.csail.mit.edu/classes/6.001/abelson-sussman-lec... (iirc, streams & the metacircular evaluator)

http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-27.html...

http://www.bookshelf.jp/texi/onlisp/onlisp_16.html#SEC107

-----

3 points by sjs 6308 days ago | link | parent | on: Arc Indentation Syntax

I'm all for something like this, but it's tricky. SRFI 49 looks pretty good but I have not tried it.

There are some thoughts here[1], though I don't like how he's moved the procedure outside the parens to match algol-like languages and I don't like the curly braces stuff either.

[1] http://www.dwheeler.com/readable/

-----

1 point by sjs 6308 days ago | link | parent | on: Core language addition suggestions

Using = to test for equality is confusing in an Arc forum. :)

1. This could be added without introducing a new reserved word. I have a git branch on my machine here where < and > return their first argument if the comparison succeeds.

2. Seems handy. I would put the operator before the number to compare just because it reads better, though I realize the op varies the least. The default of testing (is (len lst) 1) seems arbitrary, but I guess (no lst) takes care of the most common length test so maybe it's useful. Also, (is 1 (len lst)) is only 3 chars longer than (length? lst). Personally I like the ? suffix to denote predicate fns but I don't think pg does (or he would use them). For Arc I would suggest (len? ...).

I'm not sure about 3 and 4.

4. It seems backwards to put the (< n (len lst)) case first, no? I would put (< (len lst) n) first, then (is (len lst) n), then (> (len lst) n).

-----


If you think of the . here as Haskell's cons (:) then it makes sense. All the same, (x y . zs) can mean the exact same thing, not to mention it is shorter and familiar.

-----

2 points by almkglor 6308 days ago | link

Weird....

  arc> '(x . y . z)
  (y x z)

-----

5 points by soegaard 6306 days ago | link

Arc uses the PLT Scheme reader. The PLT Scheme reader has a non-standard (as compared to RnRS) extension, namely the double-dot notation. The double-dot notation is used to write "infix expressions".

Consider:

  (x . < . y)  is turned into  (< x y)
  (integer? boolean? . -> . void?) is turned into (-> integer? boolean? void?)
This reader extension can be turned off, but setting the appropriate parameter.

-----

1 point by sjs 6307 days ago | link

That is strange, and probably a bug. You can use up to 2 dots and the last dot is handled first, consing x and (z . nil) then consing y and (x (z . nil)). '(w x . y . z) gives (y w x z).

I can almost see how this bug appeared. Searching for the first part of a dotted expression yields (w x), and then searching for the 2nd part yields z. For some reason the expression becomes '(y . (w x z)); that I cannot explain without looking at the code.

-----

1 point by sjs 6311 days ago | link | parent | on: Z SHRTR BTTR?

As I said in a comment on the post, destructuring binds become ambiguous with the proposed change. I don't think it would work.

-----

2 points by sjs 6311 days ago | link | parent | on: Suggestion for [... _ ...]

This is already being discussed in a few threads.

http://arclanguage.org/item?id=1227

http://arclanguage.org/item?id=1329

-----

2 points by sjs 6311 days ago | link | parent | on: core language thingies

When that is true it evaluates to t.

  arc> (= a 2 b 5 c 3)
  3
  arc> (aif (> (+ a c) b) (= a it))
  nil
  arc> a
  3
  arc> (aif (>= (+ a c) b) (= a it))
  t
  arc> a
  t

-----

3 points by greatness 6311 days ago | link

good point, I should have thought that one through. Perhaps we should consider changing the return value of ">" so I'm correct? :P

It seems more useful to have the return value be the greater number if it is true, and since all non-nil values are true, it wont break any existing code. For a > b, consider the following:

  (> a b) => a
  (> b a) => nil
We can make a new > procedure which does this:

  (def >? args
     (if (apply > args) (car args) nil))
repl:

  arc> (>? 5 2)
  5
  arc> (>? 2 5)
  nil
  arc> (>? 7 5 2 3)
  nil
Then, using my definition from before:

  (aif (>? (+ a c) b) (= a it))
It shall now work. Now I'm not stupid anymore. :p

-----

1 point by sjs 6311 days ago | link

Makes sense to me. It's a trivial change in ac.scm for < and >. What about (<= 1 2 3) and (>= 3 2 1)? The easiest way to do the same for those two is to return the last value compared, which would be 3 and 1 respectively. That doesn't exactly jibe with < and > though so I hesitate to make such a change. Thoughts?

It seems logical that <= and >= should also return some meaningful value if < and > do. If we come up with something good I'll push it to the anarki repo (git wiki). Although, we could always just ignore <= and >= for now.

-----

1 point by greatness 6307 days ago | link

Why not follow the same idea as < and >:

  (def <=? args 
    (if (apply <= args) (car args)))

-----

1 point by sjs 6306 days ago | link

I should have been clearer. I agree the semantics should be the same, I just didn't see an immediately clean way to add that to the current, recursive <= and >= functions. A thin wrapper would work just fine.

-----

1 point by greatness 6302 days ago | link

Yeah, either that or use a lambda function inside their definitions:

  (def >= args
    (let f (afn (ar) (or no.ar
                       (no:cdr ar)
                       (and (no:< car.ar cadr.ar)
                       (self:cdr ar))))
      (if (f args) car.args)))

-----

1 point by sjs 6311 days ago | link | parent | on: core language thingies

I would just use this first form below. A macro you may be able to adapt for your purposes follows.

  (let a2 (+ a c)
    (if (> a2 b) (= a a2)))

  (mac =if (var expr test)
    (w/uniq result
      `(let ,result ,expr
         (if (,test ,result) (= ,var ,result))
         ,var)))

  (=if a (+ a c) [> _ b])

-----

More