Arc Forumnew | comments | leaders | submit | absz's commentslogin
2 points by absz 6473 days ago | link | parent | on: logo

I didn't see that... that's clever, but a little too hard to see for my taste.

-----

5 points by absz 6473 days ago | link | parent | on: Predicates: `is...' versus `...?'

You're what about the idea? Ambivalent? Inquiring minds want to know!

EDIT: I'm not trying to be rude, but sometimes the internet does not convey nuance very well. Don't take it that way, if you please.

-----

4 points by nex3 6473 days ago | link

Sometimes people who post to the internet don't proofread their posts :p.

The word I meant to put in there was "dubious." Sorry about that.

-----

2 points by absz 6473 days ago | link

Thank you, good sir.

And I completely concur (great word choice)--I'm working in a text editor right now (TextMate, not Emacs), and it's perfectly suitable. Forcing use of an IDE, or biasing towards it, would turn me away from the language.

-----

7 points by absz 6474 days ago | link | parent | on: Arc compiler for .NET

While Unix did win, that doesn't mean that Unix's names won. It's Unix's features that won. So it's reasonable to provide certain operations, but implementing them in terms of (system "unix-command-name ...") is not.

Of course, I use Mac OS X, so it's not like I'm adversely impacted. But the point still stands.

-----

2 points by absz 6474 days ago | link | parent | on: Map et al arguments are backwards

You can even be cleaner: $car is $.car (though this doesn't work for $.$.car). But I don't think this is really a specific case of partial application (though I see where you're coming from). While partial application would be ((map car) '((1 2) (3 4) (5 6))) and this would be ($car '((1 2) (3 4) (5 6))), the biggest win (for me) is not the partial application aspect, but the conciseness of having just one character, as opposed to (currently) ([map car _] '((1 2) (3 4) (5 6))) or ([apply map car __] '((1 2) (3 4) (5 6))), or even the partial application version. And even so, this strikes me as more similar to a request for explicit partial application, which is already implementable, than implicit partial application.

-----

4 points by cchooper 6474 days ago | link

Yes, it was the conciseness I was after. The syntax was inspired by K, where you can do this by putting a ' before a function name.

Of course, K often looks like line noise, but then K takes this technique to its logical conclusion and uses special syntax for everything. There's no need to go that far.

-----

1 point by absz 6474 days ago | link | parent | on: Map et al arguments are backwards

Since most languages are SOV and SVO, Lisp already does not read like most human languages. Lisp is either VSO or VOS (depending on how it is written); the verb (function) comes first. However, the English or math-speak phrase here is "map f onto x". It is not "map x through f" or "map x by f;" neither of these is ever used. Set-builder notation writes { x/2 : x \in Z }; this is, in many ways, what map is based on, and it puts the function before the list. I find (map xs -) to be far less readable than (map - xs), not to mention (map xs ys +) vs. (map + xs ys). Furthermore, this way of writing it mimics function application: (car x) becomes (map car xs), and so on.

There is a slight gain in indentation-based readability with your version, but I'm not convinced it's substantial enough to warrant the less-readable, less-regular, less-common inversion to be the standard; at most, a provided variant, but probably something that one should define oneself.

And for what it's worth, if the function is particularly long, I usually write

  (map
    [foo (bar _)
         (frob nitz)
         (xyzzy (quux _ _)
                alpha)]
    betas
    gammas)
which preserves the visibility of all the arguments.

-----

1 point by tokipin 6474 days ago | link

i see your point about it mimicking function application, and that seems to me the reason if there was any for why that order was chosen

> I find (map xs -) to be far less readable than (map - xs), not to mention (map xs ys +) vs. (map + xs ys)

well, if the function is named, the order isn't as significant. i personally don't see a difference in either of those pairs, but compare (map + xs ys) to a version where + is a lambda, and likewise with (map xs ys +)

i wonder which usage is more common: map with a named function, or map with a lambda. i'm sure it is the lambda usage, but i haven't programmed much in lisp. it would be interesting to analyze some code and see some numbers

  (map betas gammas
      [foo (bar _)
           (frob nitz)
           (xyzzy (quux _ _)
                  alpha)])

  (map betas gammas (fn (a b)
      (foo (bar a)
           (frob nitz)
           (xyzzy (quux b a)
                  alpha))))
also, it could be made to accept any order. though i don't see a reason for that besides serving as a model for other functions w/ respect to the implied underscore notation

-----

1 point by absz 6474 days ago | link

Clearly, readability is largely personal preference. As I said, I like the syntax of your version for lengthy anonymous functions. But I don't see it as a huge net win. It might, on the other hand, be nice to have a mapover macro which turned

  (mapover as bs ... ys zs (a b ... y z)
    (do-stuff a b ... y z))
into

  (map (fn (a b ... y z) (do-stuff a b ... y z))
       as bs ... ys zs)
which might be clearer in the really-lengthy-function case. Here it is (lightly tested):

  (mac mapover (arg1 arg2 arg3 . arg4+)
    " The last two arguments to mapover are treated as the parameter list and body
      of a function `f', which is then applied to each element of the given
      sequences (the other, previous arguments) in turn; a list consisting of the
      results of this function is returned.  In short, this is equivalent to
      (map f arg1 arg2 ... argN), where `f' is the aforementioned constructed
      function.
      Note that there is *not* an implicit `do' around the body of the function;
      if there were, it would be impossible to tell where the lists ended and the
      function began.
      See also [[map]] [[each]]. "
    (withs (args  (apply   list arg1 arg2 arg3 arg4+)
            body  (last    args)
            parms (car:cut args -2 -1) ; 2nd to last
            lists (cut     args  0 -2))
      `(map (fn ,parms ,body) ,@lists)))
Note that it's limited in that there is no implicit do around the body of the function; since it can take any number of lists, there would be no way to tell where they stopped and the function began. Also note that this may well rely on the Anarki, but I'm not 100% sure if it does.

(And I'm sure someone will tell me that CL's loop can do this in 3... 2... 1...)

Overall, I do think that (map f xs) is cleaner in the named-, short-, and moderately-long-function cases, but it's always possible to write an inversion if you think differently. But what do you think of mapover as another approach?

-----

1 point by tokipin 6474 days ago | link

i wouldn't mind that, though it would probably be considered repetitive with map, and the first thing i would do would be (= map mapover) [edit]oops, macros aren't first class... yet

ya'll confuse me wit dem macros @_@. i made my own function called nap (the other option was pam, which rolls off the tongue with an undesirable cooking-spray sort of feel)

  (def nap args
       (apply map (car (rem acons args)) (keep acons args)))
i'm not exactly sure if it works as it should but it seems ok. i noticed a nifty application of this any-order form:

  arc> (nap '(1 2 3) < '(3 2 1))
  (t nil nil)

-----

2 points by absz 6474 days ago | link

Note that mapover is less general than map. It's explicitly designed for the "long anonymous function" case, so you cannot do

  (mapover '(1 2 3) '(4 5 6) +)
; instead, you must do

  (mapover '(1 2 3) '(4 5 6) (x y)
    (+ x y))
. This is why it is a macro: it needs to treat its last two arguments as part of a function body, so it cannot evaluate them. As a macro, it can package them up and put them in a function, which can be passed to map along with the lists.

nap is a clever function, but will oddly allow you to write (map '(1 2 3) < > '(4 5 6)), which is meaningless. Nevertheless, It's not a terrible idea.

-----

1 point by almkglor 6474 days ago | link

  (mac mapeach (var . rest)
    (if (acons var)
        (with (vals (firstn (len var) rest)
               body (nthcdr (len var) rest))
          `(map (fn ,var ,@body) ,@vals))
        (let (val . body) rest
          `(map (fn (,var) ,@body)) ,val))))

-----

1 point by absz 6475 days ago | link | parent | on: Map et al arguments are backwards

That's not quite true, though. As I pointed out below (http://arclanguage.org/item?id=4704), you can set up map so that you could write

  (def dotprod (xs ys)
    (apply + (map xs ys *)))
Now, I'd rather have map stay as it is, as I've said. One should have fmap for "flipped map" which does this, and it may or may not belong in the core. After all, (map f xs) does read better than (map xs f). But even so, it is doable.

EDIT: The more I look at this, the more wrong it looks. I'm even more inclined against this; even if we have it, it shouldn't be called something so similar to map.

-----

1 point by absz 6475 days ago | link | parent | on: Map et al arguments are backwards

That's not necessarily true; as I pointed out further down (http://arclanguage.org/item?id=4704), you can get the effect you want. On the other hand, you do take a speed hit. I'm inclined towards supporting both, but swapping the args is very easy to write and may not belong in the core.

-----

1 point by absz 6475 days ago | link | parent | on: Map et al arguments are backwards

But when? That may be the single biggest change I want, actually--much of the rest is implementable within Arc, but this is not. Certainly, when that happens this is trivial, but it hasn't yet, and there's no inkling of when.

-----

4 points by tel 6475 days ago | link

Well, pg has at least suggested that he will add that functionality. This is the first I've seen of this presymbol operator.

If you can't wait, implement this or presymbol syntax into Anarki.

-----

1 point by absz 6476 days ago | link | parent | on: Map et al arguments are backwards

I really like this idea, but I don't know that $ is the best choice. On the other hand, I can't think of something better... ^car? &car? At any rate, fantastic idea.

-----

1 point by absz 6476 days ago | link | parent | on: Map et al arguments are backwards

Hmmm, I see what you mean. On the other hand, one might also often do something like (keep even mylist), which doesn't have that problem and does, I think, read better. One good option might be to provide both forms (map and fmap (f for flip or function), for instance)--map would be used where the list was longer, and fmap where the function was. You could even maintain the n-arity of map by doing

  (def map (xs arg . args)
    (withs (args (cons arg args)
            f    (last args)
            lsts (firstn (- (len args) 1) args))
      #;(...)))
To be clear, I think that providing both is better, or at least providing flip by default in arc.arc. But it's worth thinking about.

-----

More