Arc Forumnew | comments | leaders | submit | prestonbriggs's commentslogin
1 point by prestonbriggs 2024 days ago | link | parent | on: With and withs

I should have given more info. If, while using "with", I type

  (= a (test))
things look good. But if I then type

  (a!get)
arc complains

  Error: " get: arity mismatch;\n the expected number of arguments does not match the given number\n  expected: 1\n  given: 0"
Adding to the general confusion, if I type

  (a!set 1)
arc complains

  Error: "Function call on inappropriate object #(tagged mac #<procedure: set>) (1)"

-----

3 points by prestonbriggs 2024 days ago | link | parent | on: With and withs

I wouldn't think it would make a difference. The other names are all bound to functions, so we should be able to bind them in any order.

-----

3 points by akkartik 2024 days ago | link

Try running without your code.

    arc> (help get)
    [fn]  (get i)
    Returns a function to pass 'i' to its input.
    Useful in higher-order functions, or to index into lists, strings, tables, etc.
    Examples:
      arc> (get.2 '(1 2 3 4))
      3
      arc> (get!b (obj a 10 b 20))
      20
      arc> (get.9 sqrt)
      3
      arc> (map get.2
                '((a b c)
                  (1 2 3)
                  (p q r)))
      (c 3 r)
    nil

    arc> (help set)
    [mac] (set . args)
    Sets each place in 'args' to t.
    nil
These are the functions you end up calling because your dispatch can't see the earlier get and set bindings.

-----

3 points by kostas 2024 days ago | link

Look at the definition of with and withs at https://github.com/arclanguage/anarki/blob/master/arc.arc

The macro definition of with creates a function with all the names as inputs and the body of the with as the body of the function. The newly created function is called with the definitions of each name, which are effectively in independent namespaces.

The withs definition, however; recursively calls itself so that each succeeding name sees the definitions of previous names.

I believe the difference is historically due to higher speed of with. In modern programming it probably makes sense to use withs everywhere and only change to with in places where optimization is necessary.

-----

4 points by akkartik 2024 days ago | link

I actually tend to the opposite: use with everywhere unless I need withs. The reason isn't performance. It tends to make code more elegant to not rely on the order in which things are defined. And when I'm reading code, with gives me the warm fuzzies that the code is going to be cleaner. When I see withs I slow down to look at the dependencies between the bindings.

-----

3 points by zck 2024 days ago | link

Similarly to this, when I'm writing Java, I use `final`^1 everywhere I can. It's nice to be able to know that anywhere later where the variable declared final is in scope, it will have the same value as at the point it's set. I don't need to look through any code to see if it's rebound; I know it hasn't been.

[1] "final" is kind of like "const", if I understand `const` right. `final int x = 3;` means that it is an error to later have the line of code `x = 4;`.

-----

3 points by prestonbriggs 2024 days ago | link

OK, I get it, thanks. In scheme, I would use letrec for this situation; my intuition for Arc isn't very well developed.

-----

6 points by prestonbriggs 2503 days ago | link | parent | on: Operating Systems

I know of 2 examples of Lisp being used to develop an OS (there may be more): one by Symbolics (called Genera) and the other by Lisp Machine Inc (aka LMI). Apparently both of these descended from code developed at MIT's AI Lab. Googling, it sounds like some of the source code for one of the versions was released as open source.

Of course, Lisp Machine Lisp (or Zeta Lisp, et al.) are not the same as Arc, but I expect that what you can do in one, you can do in the other. Small matter of programming :-)

The interesting question is not the implementation language, but what you intend to build.

-----

6 points by prestonbriggs 2503 days ago | link | parent | on: How many people still lurk here?

Howdy

-----

3 points by prestonbriggs 2511 days ago | link | parent | on: At-sign in string

Got it, thanks.

I guess the quote idea came from me thinking that the strings were being evaluated. My untrained mind thought "strings evaluate to themselves", but apparently not. So I used the single quote to prevent evaluation.

-----

2 points by akkartik 2511 days ago | link

And it worked! Nicely done.

-----


I quite like ':' for function composition, especially in situations like this

  (map odd:car '((1 2) (4 5) (7 9)))
where you're composing a new function to pass along as an argument.

-----

3 points by rocketnia 2513 days ago | link

Well, that's a use case Arc supports and Parendown doesn't. :)

Depending on the example, Parendown can get close:

  (map odd #/map car '#/(1 2) (4 5) (7 9))

-----

0 points by prestonbriggs 4738 days ago | link | parent | on: AVL trees

Your use of hash tables to represent nodes in the AVL tree bothers me a lot. Yes, you get convenient notation, but it's disgusting, both practically and algorithmically, in terms of both space and time.

To see why, re-implement your stuff in something simple, like C or assembly, then measure space and time consumption. Compare using structs for nodes versus hash tables.

Just because it's wrapped up in pretty syntax doesn't make it efficient for use in all circumstances.

Might play with a C version of alists, versus hash tables, versus binary tree while you're at it. They're all useful, but in different circumstances. Implementing every "dictionary" with one or the other data structure is a mistake. You need to choose the correct data structure to match your application. It's an interesting engineering problem.

Preston

-----

4 points by waterhouse 4738 days ago | link

What I was doing was getting the AVL tree to work (which, by the way, took a certain amount of thinking, debugging, and rewriting). Implementing them with hash tables, with convenient notation, was entirely appropriate for the task at hand. And now that I've got it in working form, it's easy to go and replace the hash table parts with structs or something. In fact, I think that was pretty clearly on my mind, because I described in footnote 2, in some detail, how one might implement the nodes using things other than hash tables. It was not my intention that the nodes should forever remain hash tables. I think you misunderstand me greatly.

And by the way, I did re-implement it in C, using structs, before I wrote the original post. Here's an excerpt.

  avl_node * node_r(st_h *d, avl_node *x, avl_node *y) {
    if (x->dp > 1+y->dp) {
      if (x->lf->dp > x->rt->dp)
        return node(x->dt, x->lf, node(d, x->rt, y));
      else return node(x->rt->dt, node(x->dt, x->lf, x->rt->lf), node(d,x->rt->rt, y)); }
    else {
      if (y->rt->dp > 1+y->lf->dp) {
        if (y->rt->dp > y->lf->dp)
  	return node(y->dt, node(d,x,y->lf), y->rt);
        else return node(y->lf->dt, node(d,x,y->lf->lf), node(y->dt, y->lf->rt, y->rt)); }
      else return node(d,x,y);
    }}
Feels good, man. (The above code, by the way, fails to free() the obsolete nodes. That could be fixed if necessary.) Fortunately, I didn't really have to debug that code; I cribbed directly from my Arc code.

-----

2 points by akkartik 4738 days ago | link

A node has a constant number of fields. Who cares what the time complexity of lookup is?

Perhaps it's inefficient in use of space. But isn't it premature optimization to worry about that?

I don't see how showing an implementation for AVL trees claims to be efficient 'in all circumstances' (what is?), or how it claims that you can use one data structure for everything.

-----

1 point by prestonbriggs 4738 days ago | link

The "constant numbers of fields" is the reason there's a better alternative.

A hash table has an _expected_ constant lookup time. But it might be as bad as O(number of fields). He blows all his O(log n) complexities by putting in an expected O(1) lookup for all his field manipulations.

It's probably premature optimization to use an AVL tree in place of an ordinary binary tree, or even an alist.

I didn't see him promoting AVL trees for all uses, but I did see him suggesting they could/should replace alists.

Of course I don't mind a guy learning about AVL trees, or anything else, by implementing them in Arc or anything else. Indeed, I recommend such exercises to everyone; we learn a lot. But my feedback regarding his implementation of the nodes stands.

Preston

-----

1 point by akkartik 4738 days ago | link

"It's probably premature optimization to use an AVL tree in place of an ordinary binary tree, or even an alist."

Yeah that makes sense, thanks for bringing that up. The constants will probably drown out anything else for small structures.

---

"A hash table has an _expected_ constant lookup time. But it might be as bad as O(number of fields)."

Let me rephrase. A node has a statically constant, small number of fields. Who cares what the time complexity of lookup is?

"He blows all his O(log n) complexities by putting in an expected O(1) lookup for all his field manipulations."

I think you mean O(k) not O(1)? Since k is not n and exactly 4, which is a small number, it's not clear this is a problem.

---

May I suggest referring to the post or idea or implementation rather than to 'the guy'? I'm also finding your use of words like 'disgusting' distracting. (unless you're really feeling flamey :)

-----

1 point by prestonbriggs 4738 days ago | link

Yeah, it is distracting and I'm sorry about that. Similarly, I'm sorry to publicly snipe, 'cause I really do admire folks who make an effort to learn by doing, and better yet, write up their experiences.

But "disgust" was the word I wanted. I can't point at his choice and say "this is all wrong". Instead, I point at it and claim that it "smells" wrong to me, I'd never do it that way, bad taste, etc. Then I tried to argue about why my taste is offended.

Regarding O(1) versus O(k), I actually wrote "expected O(1)". That is, _expected_ constant time, versus guaranteed constant time. Though your point that the number of fields is a constant, 4, is certainly true.

Preston

-----

1 point by aw 4738 days ago | link

By the way, if anyone would like to use struct's from Arc it would be easy to implement. (http://docs.racket-lang.org/guide/define-struct.html)

-----

1 point by prestonbriggs 4956 days ago | link | parent | on: The use of + for non-numbers

I wouldn't do anything for a speed boost at this stage. Premature optimization and all that.

Preston

-----

1 point by prestonbriggs 4958 days ago | link | parent | on: Yeah, but is it Arc?

I guess I've got Arc on the brain these days.

-----

3 points by prestonbriggs 4972 days ago | link | parent | on: More documentation

Thanks for all of the clarifications.

I didn't find it at all easy to learn what I wanted from the source code. I mean, imagine I'm sitting here trying to write my first program in Arc. I know I need a loop, say, but which one? I don't even know the names yet. So I search backwards and forwards through arc.arc (or was this one in ac.scm, I can't remember!), finding first one variety then another. And interpreting the meaning of the source when I'm still learning is slow going. Perhaps you've forgotten :-)

Searching the forum wasn't much better. Imagine searching for "cache". Short words are handy to type, but don't yield useful search terms.

So I decided to write things down where I could print them out in a single command, yielding a relatively compact description, and look them up conveniently.

Preston

-----

2 points by evanrmurphy 4971 days ago | link

I can definitely imagine better documentation easing the learning curve for new Arc programmers. Source code can be self-explanatory, but only after you've attained a certain base level of fluency with the language. Just as the axioms have to be defined in Racket [1] before Arc can work, they have to be defined in your head before it can make any sense. So I applaud your effort.

One resource that really helped me learn faster was rntz's help system, available in Anarki [2]. It's very convenient because it gives you access to documentation right at the repl:

  arc> help.acons
  [fn]  (acons x)
   Determines if `x' is a `cons' cell or list.
      Unlike 'alist, this function will return nil if given an empty list
      See also [[atom]] [[alist]] [[dotted]] [[isa]] [[cons]] [[list]] 
  nil
  arc> help.alist
  [fn]  (alist x)
   Return true if argument is a possibly empty list
      Unlike 'acons, this function returns t when given an empty list
      See also [[atom]] [[acons]] [[dotted]] [[isa]] [[cons]] [[list]] 
  nil
  arc> help.afn
  [mac] (afn parms . body)
   Creates a function which calls itself with the name `self'.
      See also [[fn]] [[rfn]] [[aif]] [[awhen]] [[aand]] 
  nil
Had you known about this already?

[1] Or Java (http://github.com/conanite/rainbow, http://jarc.sourceforge.net/), or JavaScript (http://jonathan.tang.name/files/arclite/index.html), or Arc itself (http://arclanguage.org/item?id=11128). ^_^ I think someone did a port to Common Lisp not too long ago as well, but I can't find the link.

[2] http://github.com/nex3/arc/commits/master/help/arc.arc

-----

2 points by fallintothis 4970 days ago | link

Source code can be self-explanatory, but only after you've attained a certain base level of fluency with the language. Just as the axioms have to be defined in Racket before Arc can work, they have to be defined in your head before it can make any sense. So I applaud your effort.

Well put. My thoughts exactly. The suggestion wasn't necessarily to learn Arc by spending a couple days reading the source. I mean, that's what I did, but I was already familiar with Common Lisp. Just that once you reach a certain point (as Preston seems to have), it's not so daunting to say "hey, I wonder what filechars does?" and go read

  (def filechars (name)
    (w/infile s name (allchars s)))

-----

1 point by prestonbriggs 4971 days ago | link

I didn't know of it. Sounds great. Plus, I should be able to write a little program to grovel through his system and gen up a TeX document like mine.

Thanks for the pointer, Preston

-----

1 point by evanrmurphy 4972 days ago | link

The ambiguities of certain names in Arc really used to confuse me. acons is the cons predicate and alist the list predicate, but afn isn't the function predicate. Moreover, alist has nothing to do with alists (association lists).

Now that I have better command over the language, these things don't bother me so much. They have their own sense, and I increasingly appreciate how "externally exposed names [are] approximately hamming encoded." [1]

[1] http://arclanguage.org/item?id=11738

-----

1 point by prestonbriggs 4971 days ago | link

I don't mind short names. Indeed, one of my hopes in learning Arc is to get out from under the sheer bulk of the code I usually have to write to implement my ideas.

Preston

-----

More