Arc Forumnew | comments | leaders | submit | dreish's commentslogin
5 points by dreish 5665 days ago | link | parent | on: Last call for Arc bugs

My tendons say no thanks.

-----

3 points by stevedekorte 5664 days ago | link

Do you mean to write: my tnd sy no tks? ;)

-----

2 points by dreish 5664 days ago | link

No, because I wouldn't expect you to invest the time needed to learn a cutesy language for a one-off thing like a comment. A programming language, on the other hand ...

To be more specific, though I like Clojure a lot, compare Clojure's defmacro to Arc's mac. (The names, not the designs.) Regardless of how you learn about "mac", whether from reading source code or documentation, "mac" is not likely to be mysterious. In context, it should be pretty clear you're defining a macro, even if you haven't seen many before. (It was for me, reading Arc code a couple of years ago and not having seen many Lisp macros before.)

If you write a lot of macros, you're typing an extra five characters over and over for the rest of your life.

I'd rather pay a cost up-front (in this case a ridiculously tiny one) to save thousands of keystrokes. Keystrokes I can use for other purposes, like writing comments here.

Of course, it would be easy to just make mac a macro that expands to defmacro, but I'm not sure I like the idea of creating a unique dialect of a language.

-----

1 point by stevedekorte 5664 days ago | link

I suspect if you actually measure the increase in character count it's something like 1 extra character per 2 pages of code. If that makes a difference then maybe you should listen to your tendons. If you're typing more than a few pages of code a day, you're doing something wrong - most likely failing to properly abstract your code in one way or another.

I think the real reason for these obfuscations is that nerds like obfuscation. It makes them feel clever to understand something that looks confusing to the non-initiated.

-----

7 points by pg 5663 days ago | link

The reason you want commonly used operators to be short is so that most of the information you see on your screen is the content of your program. It's the same point Tufte makes about data-ink ratio in graphs. Conversely, long names and required boilerplate are like the stuff he calls "chartjunk."

You see the same thing in math notation. Do you think mathematicians use an integral symbol instead of writing out the word "integral" because it makes them feel clever? I think it's because the resulting bloat would make math expressions harder to read, not easier.

-----

2 points by stevedekorte 5663 days ago | link

I would agree that conciseness is a good reason to create a special symbol when it outweighs the cost of obfuscation and would only suggest measuring it and weighing the two instead of going with terseness by default.

For example, most equations have relatively few symbols and typically writing out "integral" might double that number. If it could be shown that "mac" vs. "macro" or "car" vs "first" halves your character count, then I think that would make a good case for their use. But if it only reduces the character count by a few percent or less, then AFAICS, it's not a reasonable tradeoff and can only guess that readability isn't the underlying motivation.

-----

3 points by thaddeus 5663 days ago | link

Initially I tried to make operator/variable names descriptive, but as time went on I became tired of typing every descriptive name again and again so, obviously, I tried to establish a balance between readability and convenience... However, the more I code the more I notice the names become shorter and find it takes effort to achieve meaningful names. That balance is going to be different person to person, but I will hazard a guess that the more you code the shorter the names become.

as an example (not that the function works):

    (def fill (table-name with)
         (filltable table-name with))

    (def fillcup (with size)
        (let cup size
            (fill cup with)))

    (fillcup "coffee" 8oz*)
The above is ideally how I would name names, but then find myself trying to incorporate the data type into the name...

    (def fillcup (with-string size-table)
        (let cup size-table
            (fill cup with-string)))
which I think is equally as bad as:

    (def fillcup (s tb)
        (let cup tb
            (fill cup s)))
This last one is bad as 'tb' may tell it's a table, but what is it conceptually? A size table...

So here are my options:

    * the idealized version isn't descriptive enough
    * if all my code were fully descriptive I would be
      worse off reading and typing everything.
    * the short form is just as bad as both the idealized
      version and the descriptive version.
So it doesn't surprise me that people go with the short form, the lesser of evils - perhaps ?

The worst part is that because all the options suck I end up doing things like:

    (def fillcup (with-str size-tb)
        (let cup size-tb
            (fill cup with-str)))
Which by then I hate my code and should have just stuck with the idealized or the short.

I personally wish there were a means to quickly identify the data-type without having to incorporate it into the name, something like a hover tag - this would, more often, allow myself to afford the meaningful without being overly descriptive.

(I currently use textmate to write code and the terminal for the repl).

Just and opinion from a hobby programmer with only a few hundred hours programming experience.

T.

-----

2 points by conanite 5663 days ago | link

Have a look at http://steve-yegge.blogspot.com/2008/02/portrait-of-n00b.htm... ... you might find it reeks of arrogance, or you might enjoy it:

"The sticking point is compression-tolerance. As you write code through your career, especially if it's code spanning very different languages and problem domains, your tolerance for code compression increases. It's no different from the progression from reading children's books with giant text to increasingly complex novels with smaller text and bigger words."

If my understanding is vaguely correct, Yegge argues for compact code for the same reasons pg does.

I personally wish there were a means to quickly identify the data-type

Something that an editor for a dynamic language can give you is run-time analysis of your code - so, indeed, a mouse-over could in fact give you a list of the types assigned to any given symbol. This is something I'd love to get welder to do ... it's entirely possible, in theory :)

Alternatively, you could write your own function definition macro that lets you specify param types and checks them for you at runtime:

  (typed-fn fillcup ((string with) (table size)) 
    (let ...
But my tendons recoil in horror at the implications of this. Remember: strong typing hurts your keyboard!

-----

2 points by thaddeus 5663 days ago | link

I enjoyed the first half - then he went on and on and on....

My goal is to try making code readable enough that documentation or 'metadata' is barely needed. I'm going to rework my code and start keeping my code idealized - not descriptive - not short.

I'm going see how it works when I drop the data type tagging all together and hope one day when I am a little more knowledgeable I will be able to craft a solution.

Maybe in a few years I'll let you know how it went :) T

-----

1 point by applepie 5661 days ago | link

I think I may have lost my faith in Arc.

But the comparison with math notation was enlightening.

You definitely have a point.

-----

2 points by dreish 6036 days ago | link | parent | on: Multiple Return Values?

Returning multiple values puts multiple non-GC'd values on the stack. This is fast, but capturing and using those values is somewhat inconvenient for the programmer. Returning a cons creates one other cons in the heap that will need to be GC'd for each additional value returned.

-----

1 point by almkglor 6035 days ago | link

In theory we could do this with arc2c. However, I'm not 100% sure this is necessary with a "really good" optimizing compiler.

We could defer destructuring of arguments in arc2c to as late as possible, so that we could do some amount of optimizing away 'cons cells when the cells themselves are used only for returning multiple values. Which is arguably difficult, since each stage in arc2c expects arguments to be in undestructured form, i.e. (let (foo bar) niaw ...) => (let tmp niaw (with (foo (car tmp) bar (cadr tmp)))). If arguments are kept in non-destructured form, we would need to modify the way that function parameters are stored (to handle (o foo (expression))) and check each stage in the compiler.

Edit: When optimizing raymyers' treeparse, I actually transformed parsers to CPS form in order to return multiple values without all the construction and deconstruction of 'cons cells, which helped reduce some of the overhead.

-----

2 points by dreish 6047 days ago | link | parent | on: (/ 0 0.0) = 0

Considering this is a property of Scheme, what are the odds that it would really be a bug? Not to say that Scheme is perfect in every way, but I'm pretty sure they've thought through basic arithmetic.

-----

2 points by dreish 6050 days ago | link | parent | on: Poll: ssyntax

I wouldn't want to see any of these added to the base language, but I think it's great that the anarki/git allows the user to create these, and I hope that feature makes it into the official language. Lisp is for creating domain-specific languages, and Arc is supposed to be a compact Lisp, so domain-specific syntax seems like a good thing to me.

I'm also biased, because I want to create my own syntax for a message-passing Arc to be used as the object scripting language for a multi-user VR system. (I haven't even started working on a server for it yet -- just the client and the protocol.) So something like:

  (is /parent/owner/id /owner/id)
instead of

  (is (msg (msg parent 'owner) 'id) (msg owner 'id))
I assumed I was going to have to dig into as.scm, but if there's a quicker way to do it, that's less work for me.

-----

3 points by almkglor 6050 days ago | link

Looks like you have to add something like:

  /  (msg L 'r)
capital L means left-associative, so foo/bar/nitz is grouped {{foo / bar} / nitz}.

As an aside, why not <- ? Basically parent<-owner<-id means "send 'id to the result of sending 'owner to parent".

For that matter if an object, such as parent above, is something of very specific type, you can even use the Anarki 'defcall syntax. For example if messageable objects are of type 'messageable, you can do:

  (defcall messageable (o m)
    (msg o m))
which creates the relation:

  (foo bar) == (msg foo bar), if (is (type foo) 'messageable)
Then (msg parent 'owner) is simply parent!owner. If you load the new Anarki ssyntaxes.arc, then parent!owner!id is ((parent 'owner) 'id)

-----

1 point by dreish 6048 days ago | link

Thanks for the tips.

I considered <- (along with a lot of other things), but rejected it because the left-associativity of it seemed counter-intuitive, it didn't stand out as much as slashes, and I want it to stand out because it's inconsistent with symbol syntax, it's confusing with -> which conventionally means type-conversion (and which doesn't break up symbols), and it's three times as much effort to type as /.

Slashes are fairly common in symbols, but not at the beginning (except for / itself), so it's unambiguously parseable, though maybe it won't work with this system, now that I think about it. I don't see how to prevent embedded slashes from meaning anything special without the first slash. I.e., I want foo/bar/nitz to be one symbol, but /foo/bar/nitz to be a symbol and two msg calls. Maybe that's too hairy, but I'd hate to break things like w/uniq.

I guess the general solution to any syntax that is confusing to people is a good syntax-highlighting editor.

-----

3 points by almkglor 6048 days ago | link

Well, for that matter having (foo msg) mean "send msg to foo" would be much shorter, and also shows that Scheme was originally a synchronous message-passing language anyway.

-----

1 point by dreish 6047 days ago | link

Yeesh, why didn't I think of that?

That seems clearly to be the best way to do it. Thanks again.

-----

1 point by dreish 6051 days ago | link | parent | on: defmacro mac?

What does it buy you, other than four more steps toward carpal-tunnel syndrome?

-----


Although this does bring up an unfortunate characteristic of 'is':

  arc> (is 0 0.0)
  nil
It might be nice to have an == that does a numeric comparison, if floats and ints are always going to be considered unequal by 'is'.

-----

2 points by tokipin 6064 days ago | link

in the meantime i have devised a clever scheme i call "natural coercion":

  arc> (with (x 0 y 0.0)
          (is (+ x 0.0) (+ y 0.0)))
  t
it can be toolified as:

  (def eq args
      (apply is (map [+ _ 0.0] args)))

-----

2 points by eds 6064 days ago | link

I would have expected 'iso to work for that, but it also returns nil.

  arc> (iso 0 0.0)
  nil

-----

1 point by sacado 6063 days ago | link

You're right. This is really strange as 0.0 is considered as an 'int.

-----

3 points by rincewind 6063 days ago | link

This may be related to http://arclanguage.org/item?id=5720

-----

1 point by sacado 6063 days ago | link

Hmmm... very possible...

-----