Arc Forumnew | comments | leaders | submitlogin
2 points by akkartik 5028 days ago | link | parent | on: Remove all duplicates from a list

Here's how I would write unique_list without changing your algorithm:

  (def unique_list (ls (o uniq_ls) (o x))
    "Returns ls without duplicates; order unspecified.
    Only works for lists of numbers."
    (if (no ls)
          uniq_ls
        (no uniq_ls)
          (unique_list (sort < cdr.ls) (list car.ls) car.ls)
        (iso car.ls x)
          (unique_list cdr.ls uniq_ls x)
        'else   ; personal idiosyncracy not an arc idiom
          (unique_list cdr.ls (cons car.ls uniq_ls) car.ls)))
1. I assume you only want it applied to lists of numbers? Otherwise sort won't work.

2. Since you're messing up the order anyway, why not return the result in descending rather than ascending order? It's faster.

3. I'd rather just pass car.ls around so I don't need an extra level of indent for y. But slight changes to the code might cause me to revisit that. Arc's ssyntax makes simple expressions look like names for free. (The performance hit is not worth thinking about.)

4. I don't like how the sort is hidden in my solution; perhaps I'm trying too hard to avoid the afn :) I've never liked that idiom, perhaps because it's so hard to indent well.

5. Optional args can often obviate the need for anonymous inner functions.

3 points by rocketnia 5029 days ago | link | parent | on: Remove all duplicates from a list

Not to burst your bubble, but Arc's "dedup" already does this. :) Here's Paul Graham's implementation of 'dedup in Arc 3.1:

  (def dedup (xs)
    (with (h (table) acc nil)
      (each x xs
        (unless (h x)
          (push x acc)
          (set (h x))))
      (rev acc)))
If you indent your code block with two spaces, it'll display as code. I think this might be how you wanted your code to look:

  (def unique_list (ls)
       "Removes all duplicated values in LS. Returns a new list"
       (= ls (sort < ls))
       ((afn (ls uniq_ls x) ;; uniq_ls -> the list we are building, x-> last inserted value
         (let y (car ls) ;; y -> actual value
          (if (no y) 
              uniq_ls ;; we're done, return list
            (is x y)
            (self (cdr ls) uniq_ls y) ;; current val is same than last one, we don't insert it
            (self (cdr ls) (join uniq_ls (list y)) y)))) ;; else we insert it and continue recursion
        ls () nil)) ;; function call

Here's a pruned-down summary:

"If we can extend an extensible type and reimplement its interface (and re-prove its invariant) so that the new implementation/proof is observationally equal to the original as far as the original cases are concerned, then our extension may as well have been part of the type all along."

"This take on the expression problem can easily generalize it to cubes, to say the least!"

Solve ALL the expression problems!

---

"I don't particularly intend for my system to support induction or recursion, at least at the proof level. It's great to be able to manage infinite families of value given only finite tools, but I see that as more of a nice-to-have feature, less essential than the modularity and convenience I'm trying to establish."

"I'm interested in demonstrating that this system ties into the foundation of mathematics with multiple relative consistency results, and ironing out any paradoxes along the way. However, I'm even more motivated to expand my model into a full programming language. With any luck, that'll help on the way to those proofs."

1 point by akkartik 5039 days ago | link | parent | on: Rudimentary pattern-matching in def

Wart knows knows no symbol unquote, only a literal comma :)
1 point by rocketnia 5039 days ago | link | parent | on: Rudimentary pattern-matching in def

"Since I posted this I ended up using backquotes for pattern matching"

I agree with Pauan. This is reasonable. ^_^ Well, beware of corner cases like trying to match literal uses of the symbol 'unquote.

1 point by Pauan 5039 days ago | link | parent | on: Rudimentary pattern-matching in def

"Is this what you meant?"

Yes.

---

"Since I posted this I ended up using backquotes for pattern matching"

That sounds reasonable. It's what I would have done in the past.

2 points by akkartik 5040 days ago | link | parent | on: Rudimentary pattern-matching in def

Yes, this isn't currently legal:

  def (foo) :case a :case b  # second case is ignored
Is this what you meant?

---

I think I wasn't clear about my meaning. Consider the following definition:

  def (foo 'a b)
    ..
This can mean two things:

a) Selective-quoting: foo takes two args, the first isn't eval'd.

b) Pattern-matching: that definition of foo is dispatched to if the first arg is a.

So I wasn't sure which to use. Since I posted this I ended up using backquotes for pattern matching, so for case b) you'd end up saying:

  def (foo `a b)
    ..
2 points by Pauan 5040 days ago | link | parent | on: Rudimentary pattern-matching in def

"Only supported in def without :case. I'm basically not sure whether to support selective quoting or pattern matching. Suggestions?"

Well, I don't see any problem with that, since everything pattern matching can do, :case can do, and vice versa. So it makes sense to me to define one in terms of the other. Whether you define :case as a pattern, or patterns as :case, will depend on which strategy you think is better.

Oh, I see, wart supports only a single :case, right? If it supported multiple :case's, then you could support pattern matching and :case, right?

2 points by akkartik 5045 days ago | link | parent | on: Why Arc hasn't taken off

Ah, many thanks! I now imagine one of the many ancient, stark, beautiful churches that dot London getting rid of their ancient chairs somehow, to be eventually purchased at discount by hipster coffee shops, resulting in unbelievers like me being able to enjoy them. This mental image connects up several memories of my trip, and immeasurably enriches my world.
5 points by dcminter 5046 days ago | link | parent | on: Why Arc hasn't taken off

To answer your question about the chair - it's seating for a church or chapel. Prayer books and hymnals are kept in the pocket on the back for the use of the people in the row behind.

Thanks for the new example! The if.. nil idea is cool; I wouldn't have thought of doing stuff in the conditions in a million years :)

Your 'if example might not be contrived enough. :) Here's a way to do what you're doing in pg-Arc:

  (mac format (open close char s i flag)
    `(when (and (is (,s ,i) ,char)
                (or ,flag
                    (atend ,i ,s)
                    (and (~whitec (,s (+ ,i 1)))
                         (pos ,char ,s (+ ,i 1)))))
       (pr (if ,flag ,close ,open))
       (zap no ,flag)
       t))
  
  (if
    ... ; lots of complicated cases
    (format "<i>" "</i>" #;between #\* #;at s i ital)  nil
    (format "<b>" "</b>" #;between #\+ #;at s i bold)  nil
    ... ; lots more complicated cases
    )
A contrived 'obj example might be better....

  (if debug*
    (mac capture-debug-info ()
      '( debug        't
         dynamic-env  env
         line-num     line-num))
    (mac capture-debug-info ()
      '( debug        nil)))
  
  (obj @(capture-debug-info)
       type 'literal-expression
       val 36)
Here's one pg-Arc alternative, which is somewhat more verbose:

  (def obj+ args
    (w/table result
      (each arg args
        (each (k v) arg
          (= result.k v)))))
  
  (if debug*
    (mac capture-debug-info ()
      '(obj debug        't
            dynamic-env  env
            line-num     line-num))
    (mac capture-debug-info ()
      '(obj debug        nil)))
  
  (obj+ (capture-debug-info)
        (obj type 'literal-expression
             val 36))
Here's another, which is somewhat less flexible:

  (if debug*
    (mac capture-debug-info body
      `(obj debug        't
            dynamic-env  env
            line-num     line-num
            ,@body))
    (mac capture-debug-info body
      `(obj debug        nil
            ,@body)))
  
  (capture-debug-info
    type 'literal-expression
    val 36)
1 point by akkartik 5049 days ago | link | parent | on: Why Arc hasn't taken off

Oh, and PG has said before that closures are a rapid-prototyping technique: https://news.ycombinator.com/item?id=3099372 (via http://arclanguage.org/item?id=17279; thanks rocketnia!)

Stdout munging looks like the easiest option, really. :-p

---

"Also, arc currently uses sha1, and I updated anarki to switch to sha512. This will break existing passwords."

A way to fix this is to annotate each hash with information about which algorithm was used to make it. As users log in, hash their input both ways, and replace the stored hash on success. All of PHP's hashing functions automatically prepend algorithm information to the result, and PHP has a corresponding feature to verify that a hash (annotated with algorithm information) matches a document. PHP's format isn't very elegant, but it's the closest I've seen to a standard. (Not that I've actually seen it implemented anywhere but PHP, but that PHP developers who want to migrate to another language will end up having to parse this format from their databases and either migrate it or code to it.)

It's worth noting that one pass of sha512 isn't very secure, since the speed of the algorithm makes it easy to reverse a compromised hash by comparing it to the hash of every possible password. I'm not sure what the state of the art is, but one very common recommendation is bcrypt: http://codahale.com/how-to-safely-store-a-password/

Even Hacker News uses (or has used) bcrypt: http://news.ycombinator.com/item?id=3099372

2 points by akkartik 5051 days ago | link | parent | on: Why Arc hasn't taken off

"if a language designer fails to understand those reasons and blindly goes for standards-compliance, they won't just reap the benefits; they'll also propagate and entrench the existing defects."

Replace 'language designer' with 'programmer' and that's my whole philosophy in a nutshell.

In fact, I'd like to even generalize this past software. I was in London over the break and found this really cool looking chair everywhere with a pocket in the seat back: http://i.imgur.com/rTO8O.jpg. It looks quaint, and it's everywhere, and I kept wondering, what's the use case? What misfits[1] did the designer consider in building it? I could try to think up a few scenarios, but it's deeply unsatisfying to me to not know.

I'd love to live in a world where I can query objects I interact with for their creators, their antecedents, the design process they went through. What was the designer optimizing for? I have no idea how to do this for the real world, but perhaps one can take a stab at this for software? I think if we were better at communicating and managing the design choices made by our various software 'abstractions' we wouldn't need them to be abstractions anymore[2].

[1] http://www.amazon.com/Notes-Synthesis-Form-Harvard-Paperback.... If you haven't yet read this slim volume, I'd make it your #1 priority this year.

[2] http://akkartik.name/blog/libraries2

1 point by akkartik 5051 days ago | link | parent | on: Why Arc hasn't taken off

Ah, good point! I didn't think of it then (I think I even had the racket link in the textarea in a different context before I ended up dropping it to the floor.)
2 points by rocketnia 5051 days ago | link | parent | on: Why Arc hasn't taken off

"Racket does not provide any real depth for libraries. There's a lot of promoting for library depth, but as soon as you attempt to do anything practical you soon realize the available libraries are either really rough drafts or are largely out of date."

I've gotten the same impression of Racket libraries, but going by the article, mass-marketing of Racket would be a good way to end up with active libraries: "In other words, if you have people who need libraries, hackers will write them. When you have more libraries, your language looks more attractive to people who need them, so hackers write more of them[...]"

This rings true for me. I think Arc has experienced this phenomenon firsthand.

Anyway, although Racket lacks a variety of libraries, it has an impressive selection of features out of the box.

---

"Doesn't racket have the cobra or corba? for an oo-system?"

Racket has at least a few systems for stateful values with user-defined fields:

Scheme-style structs -- http://docs.racket-lang.org/guide/define-struct.html

Hash tables -- http://docs.racket-lang.org/reference/hashtables.html

Classical OO -- http://docs.racket-lang.org/guide/classes.html

Personally, I consider some of Racket's other systems to be on par with object systems in terms of supporting whole styles of program development:

Contracts -- http://docs.racket-lang.org/guide/contracts.html

Types -- http://docs.racket-lang.org/ts-guide/index.html

Reactive event handling -- http://docs.racket-lang.org/frtime/index.html

Continuations of various kinds -- http://docs.racket-lang.org/reference/cont.html

I haven't used any of these systems (aside from hash tables, I guess). I rarely use Racket, and when I do, I'm still getting the hang of its module system, lol....

2 points by thaddeus 5051 days ago | link | parent | on: Why Arc hasn't taken off

I can only contribute my opinion for a few items:

> "I would say Racket is exactly the language the article is begging for"

Racket does not provide any real depth for libraries. There's a lot of promoting for library depth, but as soon as you attempt to do anything practical you soon realize the available libraries are either really rough drafts or are largely out of date. So I don't believe racket meets this criteria highlighted in the article.

> "This also means Lisps should have an object system."

I'm guessing here, but I believe he's referring to an object system that incorporates high level features such as objects + instances with inheritance etc etc. He should probably read pg's Common Lisp book where I believe pg suggests that a oo-system is a great architecture that is well suited to a small set of projects and unfortunately programmers have learned to apply that system to everything they do simply because the oo-languages force them to do so (what they learn is what they know). He goes on to suggest that most projects would be more aligned with FP language paradigms (ie don't force extra layers of complexity where it's not required). And additionally that these oo features are easily implemented in FP languages should you want them ... Don't quote me on all this...I'm going off memory from reading his book over 5 years ago.

It also could be that he sees other FP languages having oo-systems ... I.e. Doesn't racket have the cobra or corba? for an oo-system? Never used it; so again I'm just going off memory here.

1 point by rocketnia 5051 days ago | link | parent | on: Why Arc hasn't taken off

Oh, I was particularly responding to "It also turns out that there's at least one company trying to scale continuation-based servers," which you said afterward. Guess you chose the example you chose, no worries. ^_^
4 points by rocketnia 5051 days ago | link | parent | on: Why Arc hasn't taken off

"I think it’s important to attract the programmers who Graham says are “the masses” or non-hackers. Without them, the real hackers won’t come to your language en masse either."

I'm not so sure about this conclusion. World-class hackers may be so preoccupied with deeper breakthroughs that one particular fledgling language isn't on their radar, sure. But the masses probably won't adopt a language unless their relatively nerdy friends, those who are willing to bend and break social norms to find better alternatives, have already used the language and recommend it.

I'm going to continue with an excerpt of the book Purple Cow by Seth Godin. http://www.fastcompany.com/46049/praise-purple-cow

  (excerpt
First, you need people who want to buy a pain reliever. While it's a huge market, it's not for everyone. Once you find people who buy pain relievers, then you need people who want to buy a new kind of pain reliever. After all, plenty of people want the "original" kind, the kind they grew up with. Finally, you need to find the people who are willing to listen to what you have to say about your new pain reliever. The vast majority of folks are just too busy and will ignore you, regardless of how many ads you buy. So you just went from an audience of everyone to an audience a fraction of that size. Not only are these folks hard to find, they're picky as well.

[...]

The old rule was this: Create safe products and combine them with great marketing. Average products for average people. That's broken. The new rule is: Create remarkable products that the right people seek out.

[...]

Differentiate your customers. Find the group that's most profitable. Find the group that's most likely to influence other customers. Figure out how to develop for, advertise to, or reward either group. Ignore the rest. Cater to the customers you would choose if you could choose your customers.

[...]

Think small. One vestige of the TV-industrial complex is a need to think mass. If it doesn't appeal to everyone, the thinking goes, it's not worth it. No longer. Think of the smallest conceivable market and describe a product that overwhelms it with its remarkability. Go from there.

  )  ; end excerpt
There isn't much hard substance in this excerpt, just some philosophy and an appeal to authority. Nevertheless, it's at least as good as what I could have said. :-p

---

"Another problem for Lisp is that the rest of the world doesn’t think or work like Lisp."

Actually, when I look at how programmers of non-lisp languages get things done, I'm regularly surprised to see how much they behave like lisp programmers.

Programmers often make EDSLs and custom parsers and preprocessors to model their problem space. Just look at Ruby on Rails, C's Yacc, and Template Haskell.

Programmers often represent their code using ad hoc structured data instead of flat text. Just look at Ant's use of XML for build scripts and MongoDB's use of JSON for database queries.

---

"It’s not hard to realise that people expect [...] to be able to call fork and have a new operating-system–level process appear."

This is a case where I'm personally oblivious and might not know what I'm missing. :)

Racket apparently doesn't have a "true" fork() (http://lists.racket-lang.org/users/archive/2005-September/00...). If not for this one detail, I would say Racket is exactly the language the article is begging for.

---

"This also means Lisps should have an object system."

That came out of left field. Based on the context, it sounds like the point of having an object system is to communicate with standard object-based APIs. But object-based APIs don't all use the same object system, so which one(s) should lisps have?

---

"This also means Lisps should have an object system. I think a basic Lisp on its own provides enough functionality to implement a good-enough object system, in much the same way that Perl’s bless gave way to frameworks like Moose. With lexical closures, a native symbol kind, and cons pairs, we can do everything any other language’s object system can do."

How does that justify adding an object system? If basic lisps already have all they need, that seems more like an argument against.

---

"[other factors] + following the Unix way = success"

I would suggest replacing that with "following the client-side Web way," but I'm afraid the result would be "success + ball of mud" either way. ;)

The rest of the world may have "pretty good reason[s] for doing things the way it does," but if a language designer fails to understand those reasons and blindly goes for standards-compliance, they won't just reap the benefits; they'll also propagate and entrench the existing defects. Admittedly, the benefits will often be worth the risk.

1 point by kinleyd 5052 days ago | link | parent | on: Why Arc hasn't taken off

Well, at least you got a response from pg regarding Arc. Now, about that outdated Arc home and install page ... :)

EDIT

More seriously:

pg "In retrospect YC would have taken over my life no matter what. It has pushed out essays too, mostly.

I don't consider Arc to have died, incidentally. You used it to say that, and I'm using it to reply. If I ever retired from YC I'd probably start working on it more actively again." [1]

The thread was quite revealing. Or perhaps it just said what we all probably already knew.

[1] http://news.ycombinator.com/item?id=5035846

2 points by akkartik 5052 days ago | link | parent | on: Why Arc hasn't taken off

Yes, I saw that between my comment and pg's response.
2 points by rocketnia 5052 days ago | link | parent | on: Why Arc hasn't taken off

Racket already represents one approach to "trying to scale continuation-based servers," thanks to its stateless servlets.

http://docs.racket-lang.org/web-server/stateless.html

"This process allows [many] continuations captured by your servlet to be serialized. This means they may be stored on the client’s browser or the server’s disk."

2 points by akkartik 5052 days ago | link | parent | on: Why Arc hasn't taken off

I take it all back. See PG's response there: https://news.ycombinator.com/item?id=5035857
1 point by kinleyd 5052 days ago | link | parent | on: Why Arc hasn't taken off

That was good post by you on HN.
1 point by akkartik 5052 days ago | link | parent | on: Hacker News is down

Yeah it happens every now and then. I'm sure the right people are aware.
3 points by akkartik 5052 days ago | link | parent | on: Why Arc hasn't taken off

Thanks! I woulda missed that if you hadn't posted this. It got me to finally post a long-gestating comment on arc's continuation-based webapp framework: https://news.ycombinator.com/item?id=5032739
2 points by thaddeus 5053 days ago | link | parent | on: Why Arc hasn't taken off

Discussion on HN: http://news.ycombinator.com/item?id=5031755

It was about a year and a half ago that I started thinking about the ethics of creating computational people, even if that isn't near on the horizon. I've now come up with a sketch of a computational model that I believe will help steer the world in a peaceful, fulfilling direction, and I describe it in this blog post.

RKN (Reactive Knowledge Networking) isn't going to be practical for a while, and by the time it is, it may be not very much like what I describe today. However, this is now the kind of programming I'm working toward.

I hope I get around to finishing some of my vague language ideas someday, rather than pushing them ever further out of reach. :-p


I don't quite know why, but I like to be pretty strict. I keep every line at 70 spaces long or less, with tab stops every 4 spaces, except for the following scenarios:

- Commented-out lines of code.

- A line of code that just can't be broken up any further. But first I try to move this line to a less indented part of the code, and then I remove other indentation on the line until it fits the best it can.

- Code that someone else has already made too long by my judgment. I try not to change someone else's style if my cosmetic change would obscure the meaningful changes I'm making, or if it would introduce inconsistency in the codebase. In this case the codebase includes any part of the revision history, branches, forks, and related projects that might be reintegrated.

In college I used 80 spaces, but that turned out to be too long to fit on my Wordpress layout without scrolling.

---

I thought it was also too long for Arc Forum, but it seems that's not true. Looks like Arc Forum supports 83 characters, at least on my user agent.

  (---10---)(---20---)(---30---)(---40---)(---50---)(---60---)(---70---)(---80---)1234
-

  (---10---)(---20---)(---30---)(---40---)(---50---)(---60---)(---70---)(---80---)123
When I switch from Chrome to Firefox, it looks like the 84-character line doesn't scroll anymore. In general, I bet it depends on the browser's default fonts and such.
More