This shows Nathan Smiths jquery web-browser desktop (http://sonspring.com/journal/jquery-desktop ) with an arc window I use to access my sheeva plug (notice 'prn' now works).
I would say, the code is put into lines naturally--the Arc edits2 definition is short enough that it fits comfortably on one line, while the Python known_edits2 definition probably does not--and then you count up the lines. (I say "probably" because perhaps some people would tolerate lines that long in their code. But I wouldn't, and it seems that neither did the person who wrote it.) What stops you from putting it all on one line and declaring victory? The fact that that's not how humans naturally read or write code; the first thing I'd do when reading such a program would be to separate it back into lines.
Anyway, if you want a more precisely standardizable measure of program length, try token count. That can't be fooled with, either by deleting whitespace or by giving things shorter names. (Though, if you wanted, you could take the program as a string, replace all whitespace with a special character so it's all one token, write a macro that converts the string back into real code, and thus convert an arbitrarily long program into one with a couple dozen tokens. Hmm. Is there any standardized measure of program length that can't be fooled with?)
> "I would say, the code is put into lines naturally"
I beg to differ. I've being reading pg's code and feel quite comfortable saying that his natural coding would have a line break in the example above - as would any of ours (unless you are unaware of the two spaces required for code on this forum - haha :)
Not a criticism of pg or his code. I think most the submissions to Norvigs site contain code where people are removing "natural" line breaks.
"Perhaps we should stop at 15 lines before we start getting unreadable code :) !"
speaks the truth.
I don't think there's any real value in creating a table ranking languages by line numbers. I do think the code pg produced does demonstrate how pleasant arc is to read while being very short.
type 'help' to see what examples exist.
'strrev' emulates switching modes.
As a note: I wasn't trying to build an IDE using wterm, rather I just wanted to be able to push out changes, have a means to look at data. etc etc.
> "The double-eval is because of macros, right?"
um - eh-hem - yep - I think I got that idea from you :)
> "Also, does your solution handle multiple expressions?"
hmmm... I hadn't actually tried that until you mentioned it here - no it doesn't, but I think that's a matter of defining the arc-handler to do so. wterm just takes what ever I type and submits all of it as a string then returns the response. I should look into that :)
> "And, does it handle 'prn well"
not really... in wterm everthing has to be typed on 1 line and everything returns on 1 line; example:
AJAX Terminal. To Begin Using type help
Terminal $ arc
arc $ (= db (obj how "wterm" what "arc"))
#hash((what . "arc") (how . "wterm"))
arc $ (pr db)
#hash((what . arc) (how . wterm))#hash((what . "arc") (how . "wterm"))
arc $ (repeat 3 (prn " all on one line "))
all on one line all on one line all on one line nil
arc $
> "Don't hesitate to ask for any help concerning your terminal."
ok thanks! :). I am going to take another look at your Evserv code to see if I can figure out handling of mutliple expressions. I will let you know if I need help.
Right now I am just so happy being able to tinker with arc via my sheevaplug; which is totally awesome! (+ nothing to do with arc, but I just got twonkeymedia server up and distributing movies and music to my TV - haha I don't need to keep my computer on anymore!!! cheapest, 2 watt, mediaserver I have ever seen).
> ok thanks! :). I am going to take another look at your Evserv code to see if I can figure out handling of mutliple expressions. I will let you know if I need help.
Right now I am just so happy
Yes, I pointed this eventual issue just that you have some ideas for what to work on next / what problems may appear. But yeah, if it fits your needs in this current state, which is already very good, just enjoy!
Oh and all your sheevaplug / twonkeymedia server stuff seems rather cool!
> Oh and all your sheevaplug / twonkeymedia server stuff seems rather cool!
'kens' got me hooked on playing with the sheevaplug. I hope this guy keeps sharing the wealth. Now I just got to come up with a practical use for arc on it.
Interesting. I had thought the purpose of HN was to push down on arc and make sure the language was capable, thus improving arc. Now it seems that arcs only purpose is make HN code work?
I'm seeing chickens and eggs fly by at hazzardous speeds.
Maybe I am reading this wrong?, but it seems to be a common response/statement.
I suspect that if you want to know about Arc's design goals, then pg's writings at http://www.paulgraham.com/arc.html is a better source than various random interpretations floating around on the forums.
Agreed. I do hope, however, that arc.v4.0 is structured in such away to move away from being news.arc centric. I hope pg chooses a different project to push down on arc. I think this would open the door to a fresh perspective.
(= x (list "One" "Two" "Three" "Four" "Five" "Six"))
(def first (xl)
(car xl))
(def next (xl (o n 1))
(withs (n (+ n 1)
nxl (cut xl 1 n))
(if (single nxl)
(car nxl)
nxl)))
(def rest (xl)
(cdr xl))
So ...
arc> (first x)
"One"
arc> (next x)
"Two"
arc> (next x 3) ; the next three
("Two" "Three" "Four")
arc> (rest x)
("Two" "Three" "Four" "Five" "Six")
arc> (next:rest x)
"Three"
arc> (rest:next x 3) ; the rest of the next 3
("Three" "Four")
arc> (last:next x 3) ; the last of the next 3
"Four"
arc> (first:next x 3) ; the first of the next 3
"Two"
That's six or so functions replaced by 3, that look like english and make sense.
first = car
last = last
rest = cdr
next = cadr
next:+1
next:+2
....
Comparing "+"/"add" to "car"/"first" is not the same thing.
"+" does mean "add" to the majority of people on earth - as its common knowledge, and thus it's intiutive. Car means "something one drives" to almost everyone.
> "all names are somewhat arbitrary, and it's ok to have names that don't relate to what they're doing if you use them enough"
Just because one can learn something faulty and get used to it doesn't mean one should accept it's faults and decide to live with it. One should strive to make it better. If this were not true - arc wouldn't exist. So why not change it?
> "+" does mean "add" to the majority of people on earth - as its common knowledge, and thus it's intiutive. Car means "something one drives" to almost everyone.
Because we couldn't think of any better alternatives. It would have been misleading to use first and rest or head and tail, because conses are fundamentally pairs; lists are one thing you can build with them, but not the only thing.
There's no conventional name in English for the first and second halves of a pair. If you have to make up names, car and cdr are pretty good choices, because they're short and the same length and naturally composable (e.g. cadr).
Basically, surreal numbers are a pair of two (surreal) numbers sets, the left one, and the right one.
0 is (() . ()), (cons () ()), where () is the empty set.
1 is (() . <surreal 0: (() . ())>)
-1 is (<surreal 0> . ())
It doesn't make sense to get the right set by saying (rest <surreal 0>), because it's just not the "rest", it's just the... cdr, i.e: the second halve of the 'cons. I mean conceptually, it's not the "rest".
2. Car means "something one drives" to almost everyone. No, no, NO. Ask, for instance, the 1+ billion Chinese people if "car" means anything to them. Just stop the fucking English-centrism. Will English be the proeminient language in 100 years? Is programming reserved to English-native-speakers? Is it good to mimic human languages in programming languages (hint: Algol VS C syntax)?
I love car/cdr because they don't mean anything.
Well actually, yes, they mean/meant something: content of {address|decrement} registry. But, in my view, they have just turn into arbitrary-chosen names for basic operations, like "+" is the arbitrary name of the "addition op" in our current arithmetic. You just learn that +/car means "this basic op", it becomes common knowledge, and you're done. I don't know, it's not even a name at this point, just the representation symbol.
I love APL (http://en.wikipedia.org/wiki/APL_(programming_language)) because it uses just symbols for ops. I love Perl's $_ / $| / $\ / etc. special vars because they don't mean anything by themselves, etc. I don't know, it just makes programmers from any country equals when it comes to speak to a computer. I love maths because nearly all the maths stuff use arbitrary-chosen "names", making people equals when it comes to speak to the Universe.
1. So is "last" not a pair too ? [edit] I see last does mean the last even when a pair. Where as rest may not. I'll check this out. In the end it just may be worth while to include rest and next as extra functions for the sake of language adoption? At an abstract level "rest" and "next" do accomplish what most expect it should.
>"No, no, NO. Ask, for instance, the 1+ billion Chinese people if "car" means anything to them. Just stop the fucking English-centrism."
I am willing to bet if you asked that question to every person on earth "what is car?" that statistically, the answer would represent my statement, even if by merit that some languages do not have a meaning for "car" and English, in my opinion, is more widely adopted. I could be wrong, but I don't feel bad about making that statement.
[Edited - deleted some of my own BS comments :) - thank you pg for having edit time]
Still- Maybe I should have written it this way:
"Car does not mean first to almost everyone"
>"Will English be the proeminient language in 100 years?"
Not sure. I think the world we be a much better place if the average world citizen spoke multiple languages.
And you never know maybe in doing so new languages could emerge and maybe there will be a "most powerful language" yet maybe it will not be widely adopted, or maybe it will.
We shall see :) (Edit - Opps - I just realized we will not)
Also I believe everyone is overlooking one point.
Scheme is already more powerful, yet not widely adopted.
I don't believe pg's goal in building arc is to make a scheme even more powerful. I'd like to think that pg acknowledges that language adoption should be an equally important factor to arcs' potential success.
About 'last. Conses are a powerful, general data type. One way you could use them is to build another little-less-general data type, a subset of them, a "list", where (list 'a 'b 'c) is (cons 'a (cons 'b (cons 'c nil))).
Then you define some functions to operate (exclusively) on this new "data type", and 'last is one of them. Exclusively: (last (cons 'a 'b)) doesn't work, because it'd have no meaning to use 'last here. '(a . b) is not a list, just a cons.
Similarly, one way you could use lists is to build a-little-less-general abstraction, association lists. Then you define 'alref/etc. to use with this new data type. But (alref (list 'a 'b 'c) 'a) doesn't work, since it has no meaning in this context.
But 'car/'cdr, they operate on raw conses, not only on lists. And I said before, IMHO, 'rest is not good, because you're assuming by using this name that it is an operator for lists only. Yes, (rest '(a . b)) would work, but its meaning is crappy here (IMHO).
But you're making an interesting point. Maybe 'rest/'first should be also included, as synonyms for 'cdr/'car because actually people almost always use 'car/'cdr when working with lists, and in list context, their meaning may be easier to understand. But this is another debate.
---
About the meaning of 'car. Sure, if you're programming in one of the current dialects of Lisp, you have some basic notions of English, even if you're Chinese. Yet, when reading some Lisp code, if I see 'car I just know it means "first halve of the pair". I mean, before you pointed out that "car" means "a vehicle" most of the time, I didn't ever think about this (valid) point when reading/writing Lisp code. That's why I don't see it as a problem.
I don't know, I suppose it's because the context is important. When I see 'map in a Lisp file, I don't think about a (geographical) map. When I see 'cons I know it's not as in "pros & cons". When I see 'table, I know it's not about a dining table. When I type `cd' in my shell, I know it means "change directory" and not "compact disc", etc.
Yes, if you ask a random guy in the street what "car" means he'll answer you "a vehicle" and not "the first halve of the pair". But it's the same problem if you ask it what "cd" or "table" means. There are ton of issues like this, even in natural languages. For instance, homonyms: a tire is both a car wheel and the feeling of fatigue.
---
About language adoption. It seems pg knows it is important: So whether or not a language has to be good to be popular, I think a language has to be popular to be good. And it has to stay popular to stay good. (http://paulgraham.com/popular.html)
OTOH, remember Arc is made for "hackers" and to be adopted by "hackers" (at least at first). And there is the "100 years" idea (i.e: no rush in adoption may not be a problem). So maybe pg's idea of "language adoption" is not the same than yours ;-)
---
> (Edit - Opps - I just realized we will not)
Funny yet true one :-)
I always felt a little uncomfortable about the "100 years" idea. I keep saying to myself it's just a catch phrase for a decent goal, trying to design something timeless. But still, it also reminds me of "I intend to set up a thousand-year Reich and anyone who supports me in this battle is a fellow-fighter for a unique spiritual — I would say divine — creation". You know, the fooliness to not want to live in the current, real, impure world.
> "I don't know, I suppose it's because the context is important. When I see 'map in a Lisp file, I don't think about a (geographical) map. When I see 'cons I know it's not as in "pros & cons". When I see 'table, I know it's not about a dining table. When I type `cd' in my shell, I know it means "change directory" and not "compact disc", etc"
Absolutely and it's "because the context is important" that I made the suggestion. I don't really care that it's called "car". I'm just suggesting that IF you're going to have a function called "last" why wouldn't you create "first", as the user will intuitively try to use it given that last exists.
You make a powerful point about cons cells being a more fundamental type than lists. I think if we really wanted english language words to describe the parts of a cons, "left" and "right" would be appropriate for what a cons is in isolation, but would unfortunately be meaningful only if you're using conses to represent binary trees. The beauty of a cons is that it's the smallest possible structure out of which one can build arbitrarily larger composites. And I'm not sure how valuable metaphors from the physical world are when contemplating abstractions - a cons is another degree removed from everyday reality than windows, buttons, dialogs, tabs, and menus are.
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.
>...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.
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?
I like "obj". After all in OOP isn't an object simply a property list of key/value pairs with initial values set to define the object?
i.e.
(= vampire (obj teeth "fangs" hair "black" food "blood"))
(= Dracula vampire)
So now we have an instance named "Dracula" of a "vampire" object....
or maybe I'm on glue thinking this was the intent....
T.
I share your guess that 'obj is a contraction of "object". I don't think it means exactly what your example suggests. Continuing your example, if you write
(= conanite vampire)
, the symbols 'vampire, 'conanite and 'Dracula all refer to the same object instance, so it's probably not what you want. In other words, you can turn conanite's hair blue like this:
(= Dracula!hair 'blue) ; *not tested*
I don't know if it's the glue, but I think 'deftem ("define template") and 'inst ("instantiate template") do what you describe here.
(deftem vampire name nil fangs 2 hair 'black requires 'blood) ; sorry, my vampire is defined a little differently
'deftem sorta kinda creates a "class" - but only with data slots, no behaviour.[1] Now, if you want to call up some vampires,
inst is pretty similar to obj, except internally it relies on a set of preconfigured "templates" which provide the set of keys (and their default values) for the thing you are going to build. It's used in blog.arc to define blog posts, as well as news.arc to define news items, and user accounts.
[1] at least, not by design, but there's nothing to stop you from assigning a function as the default value of any slot; except then it couldn't really be written to disk ...
> I think that would get me in trouble sometimes...
Yes, I can also see cases where this behaviour would be problematic.
However, I'm nearly sure if I hadn't have to look at arc.arc to modify 'for, I'd have never know of 'down.
And the day I would have the need for a reverse 'for, I'd have try in the REPL (for i n+m n), see it doesn't work, and then say to myself "OK, Arc is one of those language where the programmer has to make sure the bounds are in the right order in 'for", and I would have code a little thing to ensure that.
BUT, and CatDancer is very right, on the other hand, if you have 'for working also in descendant order, then it's "OK, Arc is one of those language where the programmer has to test the bounds of 'for if in a situation where he can't be sure the expected "max" will effectively be > to the "min"".
Trade-off, trade-off, trade-off everywhere. Is the overload of knowing yet another loop construct interesting enough because then you don't have to manually test the bounds where you're not sure what they'll be, or is it the inverse? I guess there is no universal answer to this...