Arc Forumnew | comments | leaders | submitlogin
2 points by fallintothis 5352 days ago | link | parent

  (mac myeach (first expr . body)
    (if (errsafe (eval first)) ; questionable, but essentially what 'defined did
                               ; just happens at expansion instead of compilation
        `(each _ ,first ,expr ,@body)
        `(each ,first ,expr ,@body)))

  arc> (myeach '(1 2 3) (prn _))
  1
  2
  3
  nil
  arc> (myeach v '(1 2 3) (prn v))
  1
  2
  3
  nil
  arc> (myeach (k v) '((a 1) (b 2) (c 3)) (prn k ": " v))
  a: 1
  b: 2
  c: 3
  nil
  arc> (myeach (k v) (table [for i 1 3 (= _.i (* i i))]) (prn k ":" v " "))
  2:4
  1:1
  3:9
  #hash((3 . 9) (1 . 1) (2 . 4))
  arc> (myeach (table [for i 1 3 (= _.i (* i i))]) (prn (car _) ":" (cadr _) " "))
  2:4
  1:1
  3:9
  #hash((3 . 9) (1 . 1) (2 . 4))
  arc> (macex1 '(myeach a b c)) ; note: a is undefined
  (each a b c)
  arc> (= a '(1 2 3))
  (1 2 3)
  arc> (macex1 '(myeach a b c)) ; note: a is now defined
  (each _ a b c)
  arc> (let v 2 (myeach v '(1 2 3) (prn v)))
  1
  2
  3
  nil
Any better?


1 point by palsecam 5352 days ago | link

Thanks for the proposal! Very interesting.

However, 'eval is not perfect.

   arc> (let lst '(1 2 3) (myeach lst (prn _)))
   Error: "reference to undefined identifier: __"  
   ; ^ lst was taken for the variable to bind
   ; and (prn _) for the sequence to traverse

   arc> (= glst '(1 2 3))
   (1 2 3)
   arc> (eval 'glst)  ; global scope, OK
   (1 2 3)
   arc> (let lst '(1 2 3) (eval 'lst))  ; lexical scope, KO
   Error: "reference to undefined identifier: _lst"

-----

1 point by fallintothis 5352 days ago | link

Which is what makes a macro like this so hairy: the inconsistency.

There are the lexical bindings you want to use as iteration variables

  (let v 2 (myeach v '(1 2 3) (prn v)))
and the ones you want to iterate over

  (let lst '(1 2 3) (myeach lst (prn _)))
Something about having your cake, eating it, etc.

Maybe what you want to do is specialize on whether the second parameter evaluates to an iterable object?

I'm not sure if, by the time anyone got the separate cases working, I'd like seeing this in use -- complexity creep.

-----

2 points by palsecam 5352 days ago | link

> Which is what makes a macro like this so hairy: the inconsistency.

Yes.

> There are the lexical bindings you want to use as iteration variables [...] and the ones you want to iterate over

Yes "context" stuff. See Perl.

> Maybe what you want to do is specialize on whether the second parameter evaluates to an iterable object?

Yes, it may be a way.

> don't know if I'd like seeing this in use -- complexity creep.

You are certainly wise here :-).

But you know, I don't care of 'each. It's OK if in current Arc it is too tricky to have, and I don't try anymore to have it work my way. It will anyway always be tricky and whether something like this should be used is another debate.

Actually what I care more about is the 'if behaviour. Everyone here seems to ignore this eventual issue and focus on the precise problem of 'each, but this was not my point initially.

-----

2 points by fallintothis 5352 days ago | link

ignore this eventual issue and focus on the precise problem of 'each

Certainly. It was in the back of my head when I wrote my reply. I didn't mention it because I was trying to be terse (I have a problem being long-winded), so opted to focus on something small in my post.

But I agree: macroexpansion time is kind of fuzzy in Arc. It even gets in the way of things like

  arc> (let do [+ _ 1] (do 1 2 3))
  3
which has been a source of hand-waving for awhile with no clear answer: http://arclanguage.org/item?id=9696. But that's another story (in a manner of speaking).

Not to pick on the intended each behavior (after all, why bother writing code if you don't like how it looks?) or the actual topic of this post.

-----

1 point by palsecam 5352 days ago | link

Thanks for the link and (let do ...) example. Interesting to read.

> macroexpansion time is kind of fuzzy in Arc

Well, this was the point of this post! It is important to know about the "limits" of your macros system. As CatDancer mentioned it, there are differences between them. The catch phrase "macros are evaluated at expansion time, functions at runtime, ..." is too simplistic and doesn't provide enough knowledge at some point.

> why bother writing code if you don't like how it looks?

You, Sir, are a wise man :-)!

-----