Arc Forumnew | comments | leaders | submit | absz's commentslogin
6 points by absz 5575 days ago | link | parent | on: What I really dislike about arc...

Just some thoughts on your thoughts:

(1) This one I think is the right decision. The real constructor is, after all, cons; and in fact, (is (type:cons 'a 'b) 'cons) but (isnt:alist:cons 'a 'b), since cons is more generic. Being a list is a property that certain sets of cons cells have, but it isn't their type.

(2) Again, I think this is the right decision. The point of obj is to be convenient in the simple case where you're building an object-like hash table: one with fixed fields and changing contents. I feel that table should probably take arguments like obj but without quoting (so that (obj a 1 b 2) would be (table 'a 1 'b 2)), but obj is still handy to have around.

(3) Ah, car/cdr versus first/rest. There's not really anything I have to add to this one, other than that I like the conciseness and composability. I've also seen fst and rst proposed, so that you can do frst for first:rest; make of that what you will.

(4) Yes, this is annoying. The rationale is the same as in the obj case, but I very often want to compare to non-symbols.

(5) If we accept that association lists are really just lists which have a certain structure, then we can't use special syntax, etc., as that already means something for lists. What if you have (= a '((1 a) (2 b))); would a.1 be a (since it's an association list) or b (since that's element 1 of the list)? I would also argue that the point of association lists is to be lists with special structure; if you want something like that that's its own type, that's what tables are for.

(6) I haven't really used deftem, but it does define a template; you create them using inst. On the other hand, obj creates the table right there.

I should say, by the way, that I don't think Arc is a perfect language by any means. Its bizarre naming conventions come to mind, for instance. But I happen to think many of these are non-issues (though I would be perfectly open to being convinced otherwise).

-----

3 points by thaddeus 5575 days ago | link

>(1)

Ok I can see this. Thank you for pointing this out, but I still don't see why it can't be type list.... list is more intuitive.

>(2)

I don't see how obj is convenient when you can't pass in functions, or when new users have to remember "use symbol here - oh but not here, or there when this case is true" - reminds me of i before e but not after c. Shouldn't a goal of language design be to prevent these kinds of things and focus on promoting language adoption / ease of use ?

>(5) "I would also argue that the point of association lists is to be lists with special structure; if you want something like that that's its own type, that's what tables are for."

The only use I can see for an association list is to have a key/val pairs structure that maintains order; Which tables do not. Otherwise I think alist would be dead. They don't have to be called "list" or "table" call them "directories", "catalogs" - whatever... I think there's an ease of use benefit having users being able to use the same tools in the "alist" as they do tables.

>(6) "I haven't really used deftem, but it does define a template; you create them using inst. On the other hand, obj creates the table right there."

makes sense. it's probably just related the other post... ie. why is it called obj? creates confusion.

===

Everything is a trade off. I'm not suggesting the justification as to "why" doesn't have merit, I'm suggesting Arc should try leaning more towards audience adoption and being more intiutive rather than being so strict that we care about each token, or having to be absolutely technically correct. Or to carry forward bad concepts from languages that are not well adopted even when more powerful.

IMHO T.

-----

3 points by zck 5575 days ago | link

>...I still don't see why [(cons 'a 'b)] can't be type list.... list is more intuitive.

Traditionally, there's a distinction -- if only in discussion, and not code -- made between nil-terminated conses and a cons with another terminator. If and only if a cons is nil-terminated, it's a list. Otherwise, it's simply a cons.

Making the distinction would be difficult. Right now, type just has to call pair? to check whether it's a 'cons. To have both list and cons types would require iterating down until you hit the end of the list every time type is called. I'm not sure having both types is useful. It might make things more complicated.

-----

1 point by thaddeus 5575 days ago | link

That makes sense. I just wonder if were living with the distinction because of the implementation or if the implementation could change so that distinction could go away?

Not to say I know how. :) T.

-----

1 point by absz 5580 days ago | link | parent | on: Why table ?

As I observed above (http://arclanguage.org/item?id=10528), table can't do this (unless we rotate names around, which would be a perfectly valid option), but here's a lightly-tested macro (with a terrible name) which exhibits your DWIMmy behaviour:

  (mac amphi-table args
    (cons (if (<= (len args) 1) 'table 'obj) args))

-----

2 points by proponent 5579 days ago | link

Thank you. Somehow how I missed your earlier reply.

-----

2 points by absz 5579 days ago | link

That would probably be because I made my two replies about five minutes apart :)

-----

2 points by absz 5580 days ago | link | parent | on: Why table ?

Because obj is a macro, and without table, what would obj expand into?

-----

2 points by absz 5616 days ago | link | parent | on: Mapa-b

Given the paucity of documentation, you many not have seen it, but you can also use Arc's built-in range function:

  (def mapa-b (f m n (o d 1))
    (map f (range m n d)))

-----

2 points by kens 5614 days ago | link

There's documentation at: http://arcfn.com/doc/list.html#range

-----

2 points by absz 5614 days ago | link

Yes, and you are an awesome person for doing that. However, I don't think anything "official" links to arcfn.com, so finding it is a bit difficult. And of course you haven't documented every single one of the bajillion little changes on Anarki, because you are a human being and need sleep.

Nevertheless, (isa "http://arcfn.com/doc/ 'awesome-thing).

-----

2 points by fallintothis 5616 days ago | link

Though in vanilla Arc

  arc> (sig 'range)
  (start end)

-----

2 points by pingi 5616 days ago | link

you're right, I haven't noticed it; thx.

-----

2 points by absz 5617 days ago | link | parent | on: Help defining a new intra symbol for arc.

Anarki makes this easy (or it did last time I checked---this may not have been ported to Arc3, I don't recall):

  (require "ssyntaxes.arc")
  
  (= mac-dollar $)
  
  (add-ssyntax-bottom
    $ (L (sym r))
    $ mac-dollar)
(This is untested, mind you.) There's more about this on the fora somewhere, but I can't find it...

-----

2 points by thaddeus 5617 days ago | link

I avoid using anarki - after finding numerous problems running code that works with the official pg branch. And trying to understand what anarki is doing to my code when there's little documentation - it's like having a brain seizure - noob style ;).

As a per example: http://arclanguage.org/item?id=6383 ssyntax breaks 'exit-on-eof' ?

Anyway - I always try paruse anarki to learn from it since there are great code examples, but I am hesitant to jump on the anarki bandwagon.

Hoping I learn more by working through the code and trying to understand what's happening.

Thanks for the pointer though... T.

-----

1 point by rntz 5617 days ago | link

There's a reason anarki has a stable branch. Of course, it's horribly out of date now, which is why I'm (still) working on porting some of the old arc2 anarki's more useful features to arc3, without the cruft. (The delays have mostly been caused by me dithering on what the best way of handling CatDancer's idea of keeping hacks separate is; I have most of the actual features I wanted to port done already.)

-----

2 points by thaddeus 5617 days ago | link

Agreed, but if I was using anarki stable - I wouldn't have access to ssyntax.

My intent was not to disregard anarki or the work (which I know most appreciate) rather just to highlight my experiences.

-----

2 points by rntz 5617 days ago | link

It hasn't been ported to arc3.

More accurately, a) I haven't ported it to arc3 and b) it hasn't shown up on anarki's arc3 branches last I checked. If anyone else has ported it, I'd be interested to know.

-----

1 point by absz 5617 days ago | link

Good to know. I haven't done any Arc programming lately, but if I get back into it, I may take a look at the ssyntax.

-----

3 points by absz 5619 days ago | link | parent | on: how to refactor this code?

You want

  (def ffilter1 (file func (o fldsep whitec))
    (ffilter file [func:tokens _ fldsep]))

-----

1 point by adm 5619 days ago | link

oops! I will test with this.

-----


[This is about your "quest for the ideal each", not about defined.]

Not to be a heretic, but this is where a more complex syntax shines. Or even something à la CL's loop, where you have a fixed keyword argument:

  (every x in '(1 2 3)
    (prn x))

  ; equivalent to
  
  (every '(1 2 3)
    (prn _))
Lightly tested:

  (mac every args
    (if (and (>= (len args) 3) (is args.1 'in))
      `(each ,(car args) ,(car:cddr args)
         ,@(cdr:cddr args))
      `(each _ ,(car args)
         ,@(cdr args))))
Another option would be anaphoric each:

  (mac aeach (xs . args)
    `(each it ,xs ,@args))
This produces

  (aeach '(1 2 3)
    (prn it))
It's not quite what you wanted, but it's similar. (It may also have been suggested before, I don't recall.)

-----

2 points by palsecam 5620 days ago | link

Your 'every example is very very attractive. I think I'll adopt it at this point:

1. It does the job without problematic cases, like there would be in what I describe:

   (with (lst '(1 2 3)
          v 3)
      [...]
      (myidealeach v lst (prn v)))  ; <-- v mistaken for the seq to traverse here, 
                                    ; because it is defined
2. OK, it adds some syntax and this is bad, but for the common case where I'd like an implicit '_ variable, it's as short as possible!

3. For the other cases, the extra "in" is not so heavy, and in a way it makes the expression more readable!

Thanks a lot absz!

----

For the rest:

> anaphoric each

Yes, a good idea but I don't like to have two loop constructs where one could suffise. Currently, I'm using something like that (I have a 'each_) but this sucks IMO.

However, interesting that you choose to use 'it' and not '_'. It makes me realize, maybe it would be better if there was only one of the 2, there are a bit redundant aren't they?

   (aif (car a) (prn _))  
   ; I like this, because "_" is more visible than "it", less likely 
   ; to be confused with a "normal" variable, and less english-centric 
Or:

   ([* it it] 2)  ; hmmm don't like that so much actually
This is pure personal taste however.

In the same way, this is also personal taste, but I mention this because an American/British people may not think about this kind of stuff. I prefer "list?" over "alist" because anyone used to the latin alphabet will quickly understand what it does (and even this is not the majority of people...). True story, I didn't understand what "acons", "alist" mean when I first looked at Arc (I'm French), while the Scheme way to name predicates was obvious at first sight.

> CL's loop

Ouch I'd really not copy 'loop too much however.

In a way, it is a good construct, I mean it is very powerful, but I can never remember of the syntax to do basic things, and this is why I prefer the Arc way here. 'loop is really a DSL in itself.

Thanks again!

-----

2 points by absz 5619 days ago | link

Glad I could be of assistance :)

As for the it/_ question: I hadn't noticed until writing my post that _ and it (and self in afn) were serving similar purposes; I don't really know which one I like more, though that's not something I care heavily about. (My feeling about the English-centricity problem is that if everything else in the language is already in English---if, each, and, etc.---then changing it to _ probably wouldn't make a huge difference.)

As for the function-naming issue: I also prefer the Scheme naming convention, though not for multiple-language reasons (I'm an American [mais je peux parler Français]); that's an aspect I hadn't thought of. (The a-predicate versus anaphoric thing is already annoying.) Internationalization of programming languages is a hard problem that I don't think anybody's tried to tackle, and I'm not sure how tractable it is---it would be interesting to see a language or framework which tried to explore that design space. The obvious approach is something like

  (mac si (c v f) `(if ,c ,v ,f))
  (= chaque each)
  ; etc.
The downside is that this only internationalizes the core; any library still has to support these synonyms or have a translator, and so I'm not sure how big the eventual gain is. (I think AppleScript had this once, but since applications didn't support this, that feature died.)

In my opinion (and I've barely used CL), loop is a brilliant piece of code because it's a great little DSL for iteration; at the same time, also having simpler alternatives, e.g. each, available is really handy because that way you don't need to know everything loop can do all the time.

-----

2 points by palsecam 5618 days ago | link

> then changing it to _ probably wouldn't make a huge difference

I also don't think it would be a huge difference for non-english programmers, although it may be a little win. But for my case, I don't prefer "_" just because of that. I'd say, the main reason is that "_" is more easily recognized by my parser (aka brain) as a special variable than "it" because it is an uncommon glyph. "it" gets lost in the flow of the program.

> I'm an American [mais je peux parler Français]

Now, that is not common and that is cool. I mean, not that you know how to speak French, but that you know how to speak a foreign language.

Those who know no foreign language knows nothing of their mother tongue. -- Goethe

It's not a coincidence that Larry Wall (Perl creator) studied linguistics...

> that's an aspect I hadn't thought of

Well in this case I can go to sleep happy, knowing I made you aware of something new ;-)

> a-predicate versus anaphoric thing is already annoying.

Yes! When I realized 'acons & the like were predicates, well I thought 'afn was, too...

> loop is a brilliant piece of code because it's a great little DSL for iteration; at the same time, also having simpler alternatives, e.g. each, available is really handy

Totally agreed. 'loop is something great to have as a library or something, but if it's the only way you have to do basic iteration, well, it sucks IMO. Because in top of knowing CL you have to know the 'loop stuff, which is completely different. Gosh, writing this message I realize I don't even remember how to iterate over a list while printing its elements. But yes, 'loop is extremely powerful.

Anyway, thanks once again absz, your message was really interesting to read!

-----


Almost line-for-line:

  (def brackify (openb closeb)
    [+ openb _ closeb])
  
  (= rbrackify (brackify "(" ")"))
  (= cbrackify (brackify "{" "}"))
  (= sbrackify (brackify "[" "]"))
  
  ...
  
  arc> (rbrackify "adm")
  "(adm")
  arc> (cbrackify "adm")
  "{adm}"
I suppose you could also write a macro, but I wouldn't bother:

  (def brackify (openb closeb)
    [+ openb _ closeb])
  
  (mac defbrackify (name open close)
    `(= ,name (brackify ,open ,close)))
  
  (defbrackify rbrackify "(" ")")
  (defbrackify cbrackify "{" "}")
  (defbrackify sbrackify "[" "]")
  
  ...
  
  arc> (rbrackify "adm")
  "(adm")
  arc> (cbrackify "adm")
  "{adm}"

-----

6 points by rntz 5625 days ago | link

The multiple '=s are unnecessary:

    (= rbrackify (brackify "(" ")")
       cbrackify (brackify "{" "}")
       sbrackify (brackify "[" "]"))

-----

2 points by twilightsentry 5618 days ago | link

What about a macro something like:

  (mac =map (f . args)
    `(= ,@(mappend (fn ((v . xs))
                     `(,v (,f ,@xs)))
                   args)))

  (=map brackify
    (rbrackify "(" ")")
    (cbrackify "{" "}")
    (sbrackify "[" "]"))

-----

1 point by thaddeus 5624 days ago | link

can someone explain to me how the variable adm is being passed into the function when it's not accounted for in the functions input args ?

Also - anyone notice there's now vote down buttons on the forum?

-----

4 points by absz 5624 days ago | link

The brackify function returns the closure [+ openb _ closeb]. The [... _ ...] notation means "construct an anonymous function of one argument, _"; it's the same as (fn (_) (... _ ...)). Thus, (brackify "(" ")") returns a function of one argument which, when called, surrounds its text with "()"; the text given is "adm".

The downvote buttons have been there for quite a while for me---you seem to have just broken 100 karma, so maybe it's because of that?

-----

1 point by thaddeus 5624 days ago | link

I see - thanks. T.

-----

1 point by adm 5625 days ago | link

thanks.

-----


It's not me, but from the side of the blog:

About Me

Name: Ken Shirriff

Contact me at: (prn "kens" #\@ "arcfn.com")

-----

3 points by absz 5633 days ago | link | parent | on: Newbie arc app just for fun...

What you said is correct; the only problem is that with the numbers you quoted, the total probability of rolling a number in the range [0,10) is 2/16 + 1/16 = 3/16 < 1 :) The numbers you meant to quote, as borne out by your data above, are a 10/16 = 5/8 chance to get a number in the range [0,5), and a 6/16 = 3/8 chance to get a number in the range [6,10). (Equivalently, a 12/16 = 3/4 chance to get a number in the range [0,5] and a 4/16 = 1/4 chance to get a number in the range [6,9], but since that doesn't partition the [0,10) range evenly, it's less instructive.)

-----

1 point by palsecam 5633 days ago | link

Thanks for the rectification :-)

-----

More