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.
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
"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."
"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?
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.
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.
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/
"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].
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.)
"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:
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....
> "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.
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. ^_^
"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.
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. :)
"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.
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.
"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."
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
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.
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.