I just implemented the abusive ip fix. Hopefully this should fix it. Now that I recall, I did this the very first time I set up the server and it ran fine for a loooooooong time. So long that I forgot to take that step again!
I use your code on www.geek.vn than switch to hackerstreet.in code. It is mostly similar but /whoami only. Your ARC code tunrs to 127 :-), not real IP.
Hackerstreet code helps me solve that tiny issue and also adds an "ask" tab on the top bar. I wonder how to add another one such as "blog" (so click on with access geek.vn/blog or about/contact etc...:-( Any help @akkartik. I am just an actual non-geek/coder :-)
I just want to add a link on the top bar, like a "news" tab, then the visitor click on that it will turn to http://blog.geek.vn subdomain. Anyways, the previous threat submitted by jwk is so helpful to me.
I just tried it behind apache, and the fix is still in working condition. Can you check if you made an error in adding it?
Is your codebase someplace public? Feel free to email it to me (address in profile). Or paste in that section of your srv.arc into a comment here to get some more eyes on it.
Thanks for the bug report. It is certainly good to know about, but I don't think the HN folks come by here much, and any fixes we come up with might well never make it back. You might want to inform them separately at info@ycombinator.com.
It looks like whitec[1] and therefore urlend[2] is not unicode-aware. I suspect that's true of all arc's string functions. I'll try to investigate, but I'm pretty ignorant of unicode; any help fixing this would be most appreciated. (Edit 25 minutes later: it turns out this was super easy to fix using racket's underlying unicode support -- https://github.com/nex3/arc/commit/052b560a2b)
I wonder if it'll cause any problems... in particular, Arc's "punc" is obviously not trying to be comprehensive, so maybe it was designed specifically for URL syntax?
Hmm, it was always defined in arc.arc, so I think it's intended for more than urls. Besides, why would bang be part of URL syntax? And wouldn't it also need ampersand? The original version seemed to include the characters for regular english punctuation.
Update an hour later: but I see where you're coming from; punc is only used in one function -- urlend.
Update two hours later: I found one regression in urlend: https://github.com/nex3/arc/commit/671c5ec916. We also have unit tests for markdown now, so any further regressions need only be caught once more.
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.
Very interesting! Indeed, I had though about optional args (and that is what I had done first) but didn't want sort called at each rec. I like how you fixed it. Sort might be a bit obfuscated.. But I don't find it really bothering. It's use is straightforward and self explained!
As I see it, the dot (car.ls) is syntactic sugar for applying a one arg function? Pretty clever! It replaces really well the y, no doubt.
The differences are subtle, but it definitely feels better, my personal alarm gets a bit of rest.
Use of iso. Don't know why I used is.. Question I had, can '=' be use as a comparison operator?
Also I get your use of 'else, but not exactly sure how it passes. Does it count as an expression evaluated to true, so then (unique_list...) gets to be it's true clause/case? Or is is simply not counted at all (making (unique_list...) the false clause of (iso car.ls x). Not sure if I'm making my self clear here, so I'll try and rephrase a bit.
A -> 'else gets to be an other if expression (if 'else) wich always evaluated to true -> following expression is the true clause of it. (what I think is happening)
B -> 'else isn't counted as a full s-expr (not sure it's the right way of saying this) and so it just goes along with following (unique_list...) -> Makes it the false clause of (iso car.ls x) and not interpreted as an other if. (Then, I don't understand why!)
Finally, and that's really a bonus I'm asking, but since I'm looking into making my next side-project (wich could be a long-term project) in Arc-based lisp, it could get me closer, I'll ask it anyway.
As of what I know, since PG's fully involved in YC, and so arc's development is in a semi-dead state, I'd better be at least looking at forks of it. Now, if I understood well, there are two major forks, one you are working on, that would be wart, and anarki (mistaken already?).
Would there be any difference in wart's implementation of the same alorigthm (since it shows a bit more use-case than pg's algorithm), or then, what would be wart's more natural form?
Thanks for the time! It's already more than I could ask!
"=" is always used for assignment, never for comparison. The only built-in equality function is "is", and "iso" is defined using "is".
---
"Also I get your use of 'else, but not exactly sure how it passes."
Like most Lisps, Arc has a datatype called "symbol", which is roughly equivalent to an "identifier" in other languages. Normally, if you use "else" it will refer to the variable "else", but if you use quote, it will be the symbol "else":
else ; variable
'else ; symbol
The rule for booleans in Arc is that the symbol "nil" is false, and everything else is true. The symbol "else" is not equal to the symbol "nil", therefore it is true.
The reason why akkartik used "else" is a personal style difference. It's idiomatic to just leave it off:
(if 1 ; if
2 ; then
3 ; if
4 ; then
5) ; else
---
"Now, if I understood well, there are two major forks, one you are working on, that would be wart, and anarki (mistaken already?)."
wart isn't a fork of Arc, it's a different language which has some similarities with Arc.
In particular, anarki is a true fork of Arc, which has diverged a lot, so don't expect much compatibility with existing Arc programs. But if you want all kinds of new features, I'd recommend it. I haven't used it myself though, so that's about all I can say about it.
Arc/Nu[1] is a fork of Arc I created, which should be mostly compatible with Arc 3.1, but cleans up the compiler and adds in a few new things. Naturally I recommend using this if you want something similar to Arc 3.1.
Then there's various other implementations of Arc, such as jarc and Rainbow, and an incomplete C implementation of Arc called Arcueid.
Yeah, it's problematic how to indent the "5". The above way makes it look like a test rather than an action, and indenting it further makes it seem like part of the same block as 4.
You can tell that there's no idiomatic way to deal with this because the arc/HN codebase is schizophrenic, using both in different places.
Pauan already did a great job explaining my use of else; nothing to add there. But I'll show off how it would look in wart:
def (uniqify ls into|result and|x)
"Returns ls without duplicates; order unspecified.
Only works for lists of numbers."
if (no ls)
result
(no result)
(uniqify sort:cdr.ls :and car.ls :into list:car.ls)
(car.ls = x)
(uniqify cdr.ls :and x :into result)
:else
(uniqify cdr.ls :and car.ls :into (cons car.ls result))
0. I can choose to skip some of the outer parens if that looks cleaner.
1. The function name for the def goes inside the param list to mimic the call being defined.
2. The '|' operator binds multiple names to the same argument, so that I can refer to the second arg as either result or into, etc. Multiple names might seem like a bad idea, but they allow me to reorganize the later recursive calls to uniqify to look more clean and mnemonic. If you're familiar with python's keyword args, this is the same idea.
(Though maybe I'm getting too clever in this case; if I ever try to use the and operator inside this function I'm liable to confuse myself.)
3. All params are now optional, like in javascript.
4. '=' is for equality, never assignment. And it can be infix.
It's a little confusing at the start to use colons in two different ways so close to each other, but here's how it looks with wart's syntax highlighting for vim: http://i.imgur.com/S7ZROtD.png. Since symbols with a colon at the start always evaluate to themselves just like literal numbers or strings, I highlight them the same as literal numbers or strings.
---
Feel free to ask us more questions regardless of what language you decide to use[1] for your side project. If it isn't one of the above, maybe you can teach us something.
[1] Nu is strictly superior to arc 3.1 in every way.
[Update: there's a bug in the above code. In my original and here I forgot that the call to sort requires a second arg:
(sort (<) cdr.ls)
We need parens around the '<' to keep wart from parsing it as an infix op.]
"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].
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.
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.