>> PHP took sigils from Perl, where Larry Wall said "Things that are different should look different"
I didn't know that. Perl seems to me like a monstrosity. But I'm sure there are worthwhile aspects to it.
>> language-imposed irregularity is at cross purposes with that open-endedness
I agree. There seems to be a trade-off between flexibility and readability.
>> Does the author just describe and demonstrate these things qualitatively, or are there also references to quantitative studies?
It's not that kind of a book.
>> I justify lisp syntax for qualitative reasons similar to the ones you use against it
I'm not trying to argue against Lisp. I've proposed that there may be a trade-off between flexibility and readability, and Lisp sits at one end of that spectrum.
>> Bonnie Meyer and others tried to use organization as a measure of reading ease. While this did not result in a formula, they showed that people read faster and retain more when the text is organized in topics.
The kind of readability I'm talking about is at a much smaller scale, like being able to recognize a function call or a loop.
>> There's one point potentially in favor of object-oriented programming, where some of the inheritance and data-and-behavior bundling may be formally unhelpful, but (I feel) it does establish an informally organized structure over the code. On the other hand, it's almost never exactly the organization I feel is ideal for conveying my own program. Grr, subjectivity again. x_x
I agree. I think one of the problems with OOP is that it tries to organize everything into hierarchies. Most things in the real world don't fit into neat hierarchies.
Think of the problem of finding things on the web. Before it morphed into something else, Yahoo was about organizing the web into a hierarchy. Search engines, in contrast, are not hierarchical. It's clear that the search engine approach has won out over the Yahoo approach.
3b. You don't forward racket to port 80, rather you're supposed to forward incoming requests that come to apache/nginx (which comes in via port 80) over to port 8080 or whatever port you choose to run the arc server on. This is called proxy or gateway passing.
Assuming you stick with apache, I'm still not familiar with your proxy passing implementation. It looks more like a hack using a load balancing mechanism for proxy passing and unless you're load balancing I wouldn't use it. When I used apache in the past I would load the mod_proxy module then do a normal 'ProxyPass'. You should configure according to the docs: http://httpd.apache.org/docs/2.2/mod/mod_proxy.html
Arc has fewer data types and consequently there are less methods/means required to interact with them. For example clojure has at least a dozen collection types (sets, various types of maps, vectors, seqs, lists, cons, etc, etc...) while at the same time having a variety of methods used to access them (atoms, refs etc).
This variety creates depth to the language, but it also makes the language more complex (even if appropriate). For example even the terms overlap creating confusion... I.e what's an 'atom' ? what's a 'map'? ifn? vs fn?, why does a vector get treated as a function?
So each of these "constructs" serve a purpose, some of which are to deal with state and time, or shall I say concurrency and mutability which often have to do with parallel computing or managing concurrent threads which all operate on the same object or data structure.
Currently Arc is limited to a very small set of data structures and methods to interact with. I believe arc still deals in mutability only, relying heavily on queues to manage state and time. Either way Arcs minimal set of constructs are probably well suited for many mobile code applications given you only need to manage interaction from a single user.
Thanks for your help rocketia :-P. Here are some of my thoughts and experiences after following your guide.
1/ I often use WinSCP instead of PuTTY on Windows to control VPS. Of course, we can only interact/manage the virtual private server via commands line, but in the case WinSCP helps me to upload the files easily. I tried to use fluxbox (a lightweight GUI for Ubuntu) and VNC to remote connect the server and use the "original" terminal to run racket and ARC forum. As far as I tested, whenever I turn off terminator/SSH window on Windows, the ARC forum will turn off as well. So there is no other choice for me to run source code.
2. Thanks for your investigation, however, the color on the front page does not change from grey to yellow/orange like Hacker News or ARCforum. I found out that the <tag> is "bgcolor", not "border-color", so it will not run even you tweak the code on the top of news.arc file. I believe that we need to change the color of the forum by "dealing" with html.arc file. I got the tag bgcolor (line 86) in that file but not sure how to change.
3. One of the most problem with me right now is how to "forward" the default port on racket server from 8080 to 80 which is default port of Apache. When I tried to configure my httpd file inside apache2 according to this instruction
http://nicholasblee.com/blog/hacker-news-clone-on-a-free-aws...
but it does not work. So that is the reason why I have to access the ARC forum by typing the port 8080, otherwise the apache will run the 80 port with a blank page.
Here is what I add to /etc/apache2/httpd.conf
<VirtualHost :80>
"Either way I think Arc would be a great fit for creating iOS apps as Arc has much simpler language constructs and mutability/concurrency wouldn't be as big of an issue given the localized nature of mobile code."
Sorry, I think I'm not catching all the context of this sentence. What language's "language constructs" are you comparing with Arc's? (Objective-C? Gambit Scheme? Racket?) What environment with "mutability/concurrency" issues are you contrasting with "mobile code"? (Server programming?)
I've only barely done any iOS programming, but I've done a bit of work on Android apps, and Android organizes rendering and event handling onto different threads.
"I pasted your DOM demo code twice, and then I was able to access both window.x and window.x2 from within Nulan. Is this intentional?"
Yes, absolutely. It's how Nulan ensures that every variable is bound to a single "box". This also has the nice property that all the different "versions" of a variable can be accessed from the JavaScript side.
Ordinarily you can't access the different versions from within Nulan, but "window" is one of the ways you can do so. Another way would be the "&" macro which bypasses the Nulan compiler.
---
"I also appended some DOM elements to the parent frame using "window.parent.document.append-child x", and they didn't get cleared on each update, but that's my own fault I guess. :-p"
Yeah, only the <iframe> is sandboxed. Of course you can refresh the page to clear it out. Don't worry, it'll save the text you typed in the textarea.
I pasted your DOM demo code twice, and then I was able to access both window.x and window.x2 from within Nulan. Is this intentional?
I also appended some DOM elements to the parent frame using "window.parent.document.append-child x", and they didn't get cleared on each update, but that's my own fault I guess. :-p
Good luck with your project. :) I don't know how far you'll get unless you do some coding, but it's great to see you were able to complete the installation.
---
"If you have free time, please instruct me how to customize the default color top bar (gray, not yellow like ARC forum or Hacker News)."
I'll tell you my step-by-step progress:
In Chrome, I right-click on the top bar and select "Inspect element." This causes the developer tools pane to appear. I fiddle with a bunch of colors, all "#b2b2b2" and "grey," but they're all text colors and border colors, not background colors. Finally, I find the tag that says <td bgcolor="#B4B4B4">, and modifying that color seems to work.
I search the Arc code for "B4", but I find nothing. So I convert B4 from hexadecimal to decimal and get 180. When I search for 180, I find two lines in news.arc that use this color:
Looks like the top of news.arc is a good place to configure the look and feel of the site. Arc Forum uses #ffbb33 = (color 255 187 51), and Hacker News uses #ff6600 = (color 255 102 0), so these might be the changes you're looking for. :)
---
"I re-configured httpd.conf file inside the apache2 folder but I did not work. I used command line to restart apache2 and the server responded that the was a syntax error on the file."
Can you show us what you changed? What's the exact error message?
On this forum, if you put two spaces in front of each line, it will
be formatted as code:
On this forum, if you put two spaces in front of each line, it will
be formatted as code:
On this forum, if you put two spaces in front of each line, it will
be formatted as code:
---
"BTW, I can only run ARC on my VPS by connect via VNC with a simple GUI to "activate" it."
Well, I had a VPS briefly, and I couldn't figure out how to access it with anything but PuTTY. It was pretty frustrating. Having a GUI must be nice. :-p I'll have to give VNC a try someday.
Are you looking for an even better alternative of some sort?
Awesome, now there's line numbers! Later on I'll write up a mode that will add syntax highlighting and auto-indent to CodeMirror for Nulan, but for now this will do.
You should see a little green box in the upper-right panel. If you click on it, it should pop up a dialog box that says "Hi!"
---
At this point it's already a nicer experience than entering stuff into the REPL. But I can do better. I plan to add in CodeMirror[1] support for the textarea on the left side, and add some more polish and such.
"And I am very much so against our current society and its ways of doing things, but now we're straying into non-programming areas..."
Yeah, I know, your and my brands of cynicism are very different. :) Unfortunately, I actually consider this one of the most interesting programming topics right now. On the 20th (two days ago) I started thinking of formulating a general-purpose language where the primitives are the claims and communication avenues people share with each other, and the UI tries its best to enable a human to access their space of feedback and freedom in an intuitive way.
I'd like to encourage others to think about how they'd design such a system, but I know this can be a very touchy subject. It's really more philosophy and sociology than programming, and I can claim no expertise. If anyone wants to discuss this, please contact me in private if there's a chance you'll incite hard feelings.
"Consider the keywords "private" and "protected;" they literally have no effect other than to cause compile-time errors."
Would you still consider this semantics restrictive if the default were private scope and a programmer could intentionally expose API functionality using "package," "protected," and "public"?
IMO, anonymous functions make OO-style private scope easy and implicit, without feeling like a limitation on the programmer.
---
"It seems to me, intuitively, that the kinds of mistakes that can be easily caught by the compiler at compile time are in general the kinds of mistakes that are easily caught, period."
I think that's true, yet not as trivial as you suggest. In general, the properties a compiler can verify are those that can be "easily" expressed in mathematics, where "easily" means the proof-theoretical algorithms of finding proofs, verifying proofs, etc. (whatever the compiler needs to do) have reasonable computational complexity. Mathematics as a whole is arbitrarily hard, but I believe human effort has computational complexity limits too, and I see no clear place to draw the line between what computers can verify and what humans can verify. Our type systems and other tech will keep getting better.
---
"The kinds of bugs that are hard to find are the ones that happen at runtime and propagate before showing themselves, and they are literally impossible for the compiler to find, because that would require the compiler to solve problems that are provably uncomputable."
I believe you're assuming a program must run Turing-complete computations at run time. While Turing-completeness is an extremely common feature of programming languages, not all languages encourage it, especially not if their type system is used for theorem proving. From a theorems-as-types point of view, the run time behavior of a mathematical proof is just the comfort in knowing its theorem is provable. :-p If you delay that comfort forever in a nonterminating computation, you're not proving anything.
Functional programming with guaranteed termination is known as total FP. "Epigram [a total FP language] has more static information than we know what to do with." http://strictlypositive.org/publications.html
---
"PHP is actually an interesting example, because in PHP, the rules for variable declarations are basically inverted from normal: you have to declare global variables in every function that you use them (or access them through the $GLOBALS array), but you don't have to declare function-scope variables at all. It makes a lot of sense if you think about it."
I find this annoying. My style of programming isn't absolutely pure functional programming, but it often approximates it. In pure FP, there's no need to have the assignment syntax automatically declare a local variable. That's because there's no assignment syntax! Accordingly, if a variable is used but not defined, it must be captured from a surrounding scope, so it's extraneous to have to declare it as a nonlocal variable.
I understand if PHP's interpreter doesn't have the ability to do static analysis to figure out the free variables of an anonymous function. That's why I would use Pharen, a language that compiles to PHP. (http://arclanguage.org/item?id=16586)
"If macros are really going to give programmers the power to make the language syntax their own, then language-imposed irregularity is at cross purposes with that open-endedness. I think the parentheses help programmers realize that they should look only at the variable names to determine meaningful differences between things."
That's the beauty of Nulan's syntax system: it is almost completely customizable, feels very "Lispish", and plays very well with macros. You can now have your short syntax and the benefits of "code is data is code".
Even wart's system works pretty damn well, despite being much less powerful, because it has very simple rules for how to handle things.
I think the key to making syntax play well with Lisp is to make sure the syntax has a certain amount of simplicity and consistency, and is customizable. Basically, the syntax needs to follow the list structure. Beyond that, you can make it as crazy as you want.
"The way I see it, what you're talking about still seems like a way to cater to stupid programming. Truly smart programmers don't generate any errors unless they mean to. ;)"
Then I'll reclarify and say "any programmer who's just as smart as me", thereby nullifying the argument that a "sufficiently smart programmer would never make the mistake in the first place".
---
"If you take your proposal, but add a type annotation form [...]"
Sure, if it's optional. And not idiomatic to use it all the time. The problem that I see with languages that emphasize static typing is that even if it's technically possible to disable the type checker, it's seen as very bad form, and you'll get lots of bad looks from others.
The idioms and what is seen as "socially acceptable" matter just as much as whether it's "technically possible". If I add in type checking, it'll be in a care-free "sure use it if you want, but you don't have to" kind of way. I've seen very few languages that add in static typing with that kind of flavor to it.
---
"This happens all the time, and some may call it cargo culting, but I think ultimately it's just called society. :-p"
And I am very much so against our current society and its ways of doing things, but now we're straying into non-programming areas...
"I mean Node.js gives JavaScript the side effect powers typical of OS processes, while the browser gives JavaScript a UI. With socket.io, it should be very easy to take your browser interface and use it as a command shell. I can help if you'd like. ^_^"
Alrighty. I'm still not 100% sure how you'd accomplish that, so I wouldn't mind some help.
---
"I was thinking of something easy and free like GitHub Pages. I understand if you'd like some more polish though."
Well, before I consider any of that, I have a few cool ideas I want to add in first to "nulan.html".
"I like how in PHP, variable references always have dollar signs attached. If you bring the mindset of a computer scientist only, you might say, well, the dollar signs are obviously to simplify the tokenization; if you can solve this engineering problem, you should get rid of them. But I think it probably makes a difference in helping your brain's "tokenizer.""
PHP took sigils from Perl, where Larry Wall said "Things that are different should look different" and used different sigils for different types. However, sigils in PHP, Perl, and shell syntax all make string interpolation possible, which is more of a tokenization issue. So I think sigils probably exist in PHP for both reasons.
As a side note, Groovy uses $foo or ${foo} to mark string-interpolated expressions, but that $ isn't used in other circumstances. It uses the sigil only where the tokenization really demands it.
Personally, I consider "different things should look different" to be a good justification for lisp syntax. If macros are really going to give programmers the power to make the language syntax their own, then language-imposed irregularity is at cross purposes with that open-endedness. I think the parentheses help programmers realize that they should look only at the variable names to determine meaningful differences between things.
---
"The author goes on to describe how these things determine where your eyes land and then move over the page, which consequently determines how easy or hard it is to make sense of; remarkably, it was true, as you can see from the examples."
Does the author just describe and demonstrate these things qualitatively, or are there also references to quantitative studies?
This is Arc Forum, where the regulars already know how to read lisp syntax. We may try to look at our culture with fresh eyes, but it isn't easy. And as I hope you can see, I justify lisp syntax for qualitative reasons similar to the ones you use against it, without really disagreeing with you.
Hard numbers are the kind of thing that would clarify which of these arguments should win, so that's what I hope to find in a thread about "concrete, objective reasons." I'm not surprised or offended that this discussion hasn't focused on the numbers, but I am a bit disappointed.
From the article: "Bonnie Meyer and others tried to use organization as a measure of reading ease. While this did not result in a formula, they showed that people read faster and retain more when the text is organized in topics. She found that a visible plan for presenting content greatly helps readers in to assess a text. A hierarchical plan shows how the parts of the text are related. It also aids the reader in blending new information into existing knowledge structures."
There's one point potentially in favor of object-oriented programming, where some of the inheritance and data-and-behavior bundling may be formally unhelpful, but (I feel) it does establish an informally organized structure over the code. On the other hand, it's almost never exactly the organization I feel is ideal for conveying my own program. Grr, subjectivity again. x_x
The way I see it, what you're talking about still seems like a way to cater to stupid programming. Truly smart programmers don't generate any errors unless they mean to. ;)
---
"What the type system doesn't do is restrict the programmer in order to make it easier to detect errors at compile-time."
Guarantees don't have to "restrict the programmer." If you take your proposal, but add a type annotation form "(the <type> <term>)" that guarantees it'll reject any program for which the type can't be sufficiently proved at compile time, you've still done nothing but give the programmer more flexibility. (Gradual typing is a good approach to formalizing this sufficiency: http://ecee.colorado.edu/~siek/gradualtyping.html)
I think restriction comes into play when one programmer decides they'll be better off if they encourage other programmers to follow certain conventions, or if they follow certain conventions on their own without immediate selfish benefit. This happens all the time, and some may call it cargo culting, but I think ultimately it's just called society. :-p
I've learned through bitter experience to treat all C warnings as errors, and more. The presence of a single uninitialized local variable somewhere in your program makes the entire program undefined. Where undefined means "segfaults in an entirely random place."
"The problem is that a lot of the people who find static type systems useful are also the kind of people who like safety a lot, so they want the type system on all the time. Not just to protect their code, but to prevent other programmers from making mistakes.
I don't like that mindset. Which is why I prefer languages like Ruby and Arc, even with their flaws. I don't think any restriction should be added in to prevent stupid people from doing stupid things. I think the language should only add in restrictions if it helps the smart people to do smart things. And for no other reason."
I could not agree more. I think that the idea of preventing mistakes via restrictive language features is one of the dominant ideas behind object-oriented languages. Consider the keywords "private" and "protected;" they literally have no effect other than to cause compile-time errors. It seems to me, intuitively, that the kinds of mistakes that can be easily caught by the compiler at compile time are in general the kinds of mistakes that are easily caught, period. The kinds of bugs that are hard to find are the ones that happen at runtime and propagate before showing themselves, and they are literally impossible for the compiler to find, because that would require the compiler to solve problems that are provably uncomputable. At my last job, I was working on fairly complicated web applications in PHP, and even though occasionally I'd run into a bug that could have been prevented by static type-checking, it was always in code that I had just written and wasn't hard to find. By eliminating things like variable declarations, PHP code can be made very succinct, and I think that simplicity and succinctness more than offset the risks that come from a permissive language. But I've never used a language that came with type-checking optional, so I have never made an apples-to-apples comparison. PHP is actually an interesting example, because in PHP, the rules for variable declarations are basically inverted from normal: you have to declare global variables in every function that you use them (or access them through the $GLOBALS array), but you don't have to declare function-scope variables at all. It makes a lot of sense if you think about it.
"As for socket.io... well, that's just a JS library, right? And Nulan just compiles to raw JS, so you should be able to interface with it just fine."
I mean Node.js gives JavaScript the side effect powers typical of OS processes, while the browser gives JavaScript a UI. With socket.io, it should be very easy to take your browser interface and use it as a command shell. I can help if you'd like. ^_^
---
"As for online hosting... no, not really. I mean, if somebody wants to host it, feel free, but I'd personally wait until it's all nice and polished first."
I was thinking of something easy and free like GitHub Pages. I understand if you'd like some more polish though.
I'm not sure why you bring up C. A look on Wikipedia tells me FORTRAN II was made in 1958, then BASIC in 1964, and then C in 1969-1973. FORTRAN II looks like it was clearly in the same design family as BASIC, with line numbers, multiple GOTO variants, capitalized English words for syntax, and a necessity to munge obscure memory addresses to invoke advanced functionality. :)
Just like you, the first language I learned was BASIC--specifically Applesoft BASIC--and the second was C. I liked C better because its program code was more modular (no need to push around line numbers when combining programs or inserting code) and it had variables that were local to the current procedure call, which made recursion much more useful.
Then I learned JavaScript, and I no longer had to worry about choosing specific numbers for my array sizes or fumbling with pointer operators. Then I was formally taught Java, and that's when I finally felt capable of writing just about any program: Run time allocation was now easy even when the lifetimes didn't fit a recursion hierarchy (i.e. I couldn't stand malloc() before), and the notion of behavior as part of data made it easy to pursue higher-order designs.
---
"But it seems to me that a concrete concept is easier to understand than an abstract one. The hardware gives you a concrete frame of reference."
Although I briefly programmed in C and I've occasionally read machine code, I don't recall ever considering computation hardware to be a very good frame of reference. Mathematics is where I find confidence, and user experience is where I find tangible feedback.
C tells an elaborate story of a world where memory is mostly one-dimensional, mutable, and uniformly cheap to access, where this memory contains all execution state (even the stack), and where execution takes place in a sequence of discrete steps. In our present-day world of cloud and mobile computing (not to mention the future), where we use networks, caches, distributed code sandboxes, predictive branching, cryptography, etc., this metaphor of computation is a joke at spatially large scales and only an approximation at small scales.
I suspect C feels close to the hardware because (1) historically it's been much closer, (2) CPU-scale architecture design has continued to pander to it, and (3) its elaborate story provides programmers with a chance to discover escape hatch after escape hatch, until they're trained to believe that C closes no doors to them.
---
"a character is the same as an integer holding its ASCII code, a string is the same thing as an array of characters"
If the text you need to represent is always unformatted, canned English, then a sequence of ASCII codes might be the only representation you need. However, I hardly consider all text to fall into that category. I think text can be as hard as natural language and typography, which can be as hard as UI.
Yes, absolutely. There are certain errors that absolutely cannot be worked around, like an undefined variable. Those are errors that actually halt the program. But the rest should be optional.
"How is this different from preventing stupid people from doing stupid things?"
Because the only difference is whether the error occurs at compile-time or run-time. I'm not adding in additional restrictions to make the type-system happy: if the type system can't understand it, it just defers the checking until run-time.
Thus, the type system takes certain errors that would have happened at run-time, and instead makes them happen at compile-time, which is better because it gives you early error detection. What the type system doesn't do is restrict the programmer in order to make it easier to detect errors at compile-time.
---
"If you find this kind of static analysis important"
Not really, no. Useful? Yeah, a bit. It's nice to have some early detection on errors. But my goals aren't to guarantee things. So whether you have the type-checker on or off just determines when you get the errors. A small bonus, but nothing huge. So I'd be fine with not having any static type checker at all.
It already has a command-line interface: just use "./nulan". I'm working on getting it to work with shell scripts too.
As for socket.io... well, that's just a JS library, right? And Nulan just compiles to raw JS, so you should be able to interface with it just fine.
As for online hosting... no, not really. I mean, if somebody wants to host it, feel free, but I'd personally wait until it's all nice and polished first.
I think that C has a good solution. It will compile any code that's possible to compile, but it will output warnings. I don't think it's necessary to halt compilation just to get the programmer's attention. That's what Java does, and it really annoys me.
If the type-checking is not strictly necessary, maybe you should make it an option, like -Wall.
How is this different from preventing stupid people from doing stupid things?
I've said this recently, but I like static typing when it contributes to the essential details of the program, rather than merely being a redundant layer for enhancing confidence in one's own code. Static typing is particularly meaningful at module boundaries, where it lets people establish confidence about each other's programs.
Anyway, enhanced usability is nothing to scoff at either. If you find this kind of static analysis important, I look forward to what you accomplish. :)