8 ms·
The Wake Programming Language
- bsurmanski 12y agothe Wake language was on here a few days ago, in the form of an article titled: The Rewards of Creating a Programming Language. Other discussion here: https://news.ycombinator.com/item?id=9040029 https://news.ycombinator.com/item?id=9040029
- developer-mike 12y agoGood memory! Yeah, I had posted that to Reddit, where it didn't do too well, but someone posted it here where (for some reason!) it did much better. Figured in addition to the story of creating Wake, I'd post the home page so people could look into it more!
- girvo 12y ago> for some reason I've typically found PL related articles do much better on Hacker News than Reddit, I think perhaps because of differing (but overlapping) target audiences. Always found it interesting what articles work here but not on Reddit (the converse isn't as interesting...)
- vezzy-fnord 12y agoI'm deducing an Eiffel and design-by-contract influence from this, for some reason.
- desireco42 12y agoI really like premise of the language. It does look a little strange but that is just novelty.
- developer-mike 12y agoThanks! I think with programming languages its important that it looks just strange enough. Luckily I have a few simple ideas that drive most of those unique syntaxes, hopefully making the uniqueness both justifiable and attention-grabbing. Otherwise, its just the language that I want to program in every day, and I hope others feel similarly.
- thecatspaw 12y agoIMHO the website tries to hard to portrait wake as a better language than others. Its ok to compare yourself to other languages, but the bytecount (which doesnt really say much about a language) and the coloring of the boxes leave a bad taste with me. Same in the "What Wake did without" section. Yes, you do not have those features, or bugs, but have you really "FIXED" a bug? There is no bugs you have fixed, just different design decisions. edit: The language may or may not be actually worth something, but those things make it look like they try to hard to me.
- tines 12y ago> Code as concise as javascript, with inheritance and typesafety and more Extremely minor potential nitpick: correct me if I'm wrong, but I think this sentence implies that Javascript is not type-safe, when it is indeed type-safe; it's just dynamically typed, and its type system gives meaning to all expressions (where that meaning is to signal an error in some cases).
- RussianCow 12y agoHaving types does not imply type safety. I think you're confusing "type safe" and "typed".
- vezzy-fnord 12y agoThe terms are evidently murky: http://www.pl-enthusiast.net/2014/08/05/type-safety/#comment-500 http://www.pl-enthusiast.net/2014/08/05/type-safety/#comment...
- developer-mike 12y agoCorrect, there is runtime typesafety in javascript. However, type-safety is a spectrum; truthiness and falsiness for instance is not very typesafe. I will revise this to be clearer (your nitpick is valid) but I think the heart of the issue is still 100% correct.
- gliptic 12y agoI wouldn't call JavaScript type-safe by any type-theoretic definition. It allows operations that really make no sense for the types involved ([]+{} ??).
- tines 12y agoI think that whether the semantics of the language make sense to a particular person isn't really the criterion for type-safety. The language does define what should happen in the case of the expression ([]+{}), so no violation of the type system occurs and the behaviour of the program is well defined.
- cw0 12y agoI think the top blurb would benefit from specifying what modern problems Wake is good at solving. Certainly, the rest of the docs give a better idea, but most programmers have a short attention span regarding brand new languages and won't get beyond the first paragraph.
- Rodeoclash 12y agoAgreed, I feel like every JavaScript framework of the week should have this as well. What advantages does this tool have over everything else that is similar to it?
- 0942v8653 12y agoI'm not sure I like the closure syntax, with the explicit return. Most modern languages (Swift, Rust, Python (lambdas), Lisp if I can call it modern) support implicit returns and it looks much better. Maybe it's just the juxtaposition with the JS code, but I was confused for a second by the word "return" inside the closure, thinking that it returned from the original function with just the first result. (I really like Rust's take on this with the semicolons—just leave off the semicolon to return—it makes the semicolon actually useful.)
- developer-mike 12y agoThanks! Great comment, I'd planned on adding implicit returns, and may copy rust on that one!
- stormbrew 12y agoArbitrary two cents: Rust's approach to this bothers me a lot. A missing semicolon having such a weighty meaning strikes me as one of the worst warts to survive Rust's rapid evolution. It forces you to scan very carefully to determine outputs.
- developer-mike 12y agoI can imagine so; But as a counterpoint, isn't it worse with forced implicit returns, where you never have a choice but to return something, and you have to scan the code carefully to see if it was required? Maybe I'll add a 'noreturn' keyword; single expresions are automatically returned, and you can use a 'noreturn' statement to explicitly return void despite running a non-void expression.
- stormbrew 12y agoSadly I don't really have a perfect answer to that. I'm inclined to think making all returns explicit is the right choice, and is only really a problem in a language where long returns are common (specifically in my mind is ruby, where being able to return from the enclosing function is crucial to the common uses of blocks). Arguments against in languages that don't feature this sort of thing seem to be against the length/weight of the word return. Something I've played with in languages I've worked on is named returns [1], which I like for that case. [1] https://github.com/stormbrew/channel9/blob/master/sample/c9script/hash.c9s https://github.com/stormbrew/channel9/blob/master/sample/c9s... -- see the get function definition, '-> return' names the return 'channel' and 'return <- val' calls it (which returns). Now I might consider having an implicit '<- val' with no lhs that calls the current function's return, I think. I do think a special case for single statements makes sense, though.
- zem 12y agoone very curious design decision is to allow type aliases either before or after the type. so, from the examples, you have > setIdThenSave(newid Num, Bool recursively) { ... } i like the idea of letting a type do double duty as a variable name if it's obvious in context, and being aliased by an explicit name if wanted/needed, but letting the order be irrelevant sounds like unnecessary flexibility to me - it makes writing no easier, and reading harder.
- developer-mike 12y agoThis is covered in the FAQ. Partly, I allow it because there are no parsing ambiguities with it, so why not. But moreover, depending on type name & variable names, intelligently beginning or ending with an alias can lead to extremely fluent APIs. "that(expected Bool)Equals(actual Bool)" vs "writeTo(Linkable output)". This freedom can lead to more readable APIs in any language, not just English. Of course, I do see where the complaints come from, and a part of me fears the day that someone releases a wake linter which requires aliases to follow the type. If that were to happen I think I'd nix the idea in favor of unity in the community.
- zem 12y agothat's a good point, and the line of code does read fluently. i'd still argue that blurring the "alias = noun, type = adjective" metaphor is a bad idea; you couldn't write that(expected Bool, expected Int)Equals(actual Bool, actual Int) to match on two values, for instance. on the other hand, constraining the adjective to come before the noun is an english-based convention, so you're probably right about seeing which way the community leans before doing anything.
- riffraff 12y agodoesn't the same apply to $Type ? It seems like unnecessary extra syntax, I'd prefer a simple "if there is ambiguity, name the variables".
- mahyarm 12y agoI wonder why you didn't use LLVM to help make your language?
- developer-mike 12y agoGreat question! I wanted to compile to js with a better interface than emscripten.
- david-given 12y agoBeen there, done that --- my own pet programming language (we all do one, or several) is Cowbel, at http://cowbel.sf.net http://cowbel.sf.net, and it's now on its third incarnation, generating C. The second used LLVM. The reasons I switched away from LLVM are: - the LLVM API is huge, not very well documented, and changes radically from version to version. - LLVM library consumers are not well supported by the project. Frequently what you get when install it is a set of static libraries, which take forever to link against and lead to 150MB binaries. - LLVM's supported architectures set isn't great yet. C provides a portable, vendor-neutral intermediate language which works everywhere and is easy to read and therefore debug. - targeting C makes library integration trivial (as your output program can use the library's own headers, which means ABI issues become nonexistent). I did contemplate a partial switch, where my compiler didn't link against LLVM at all but instead just spat out LLVM bitcode assembly --- but emitting C was the same amount of work and so much more flexible. The only downsides is that C can't do tail calls, and getting the debug information to match up is more work, but that's about it. (For the interested: Cowbel is an experiment at producing a minimal static duck-typed language --- all types are anonymous; you refer to objects only by their interfaces. The compiler than uses type inference to determine the actual concrete type of the object. This allows it to, e.g. use a single machine word to represent a number if you're never going to do dynamic dispatch on it, which means you don't end up with the weird schizophrenia of C++ and Java where some types are scalars and some are objects and they have different semantics. It's also an attempt at minimalism; I wanted to remove as many features as possible and still end up with a expressive language with Javascript-ish syntax. I'm really proud of the way I managed to unify scope blocks and objects... It works beautifully, and produces tight, fast code, but the compiler became unmaintainably complex and needs to be rewritten from scratch, which I haven't done yet.)
- seanmcdirmid 12y agoAs a PL designer, there is a lot to like here; the design seems quite reasonable and thought out. But what I really like is the presentation: I like how all features are summarized, pointing out what is novel, and then everything is just discussed using examples and comparisons to other languages. This is something I'll have to try when I finally get my own language off the ground :). I wonder if the author is interested in engaging with researchy PL designers. E.g. the testability orientation of the language would make for a good Onward paper, or maybe a Future of Programming workshop presentation.
- developer-mike 12y agoI'd absolutely be interested in that type of engagement, papers, and presentations. I haven't written a technical paper before, but tried to make one on the testability here: https://docs.google.com/document/d/1hT761Cl2-r7cSJV4zR69PGADBByvKeg2YZ2zWeYP1II/edit?usp=sharing https://docs.google.com/document/d/1hT761Cl2-r7cSJV4zR69PGAD...
- seanmcdirmid 12y agoThe Onward! deadline is early April (SPLASH will be in Pittsburgh in late October); the future of programming workshop (or whatever we call it) deadline will be sometime much later than that (maybe July?) and the presentation format will probably be flexible (video, paper, ...) with tracks at both strangeloop and SPLASH.
- developer-mike 12y agoThanks! These are great resources for some cool programs and I will be sure to submit!
- abecedarius 12y agoThe Javascript-for-comparison would help the case better if it didn't look unfairly poorly-coded. (And it doesn't express quite the same logic, though I don't think that makes it look worse here.) I'd have written function RecordValidator(sessionHolder) { function validateRecords(records) { return records.every(validate); } function validateRecord(record) { if (record.lastRevision !== undefined && record.lastRevision.user !== undefined) { return record.lastRevision.user.getAccounts().every(function(account) { return sessionHolder.hasAccount(account); }); } return record.revisions.map(usesLimits); } function usesLimits(revision) { return sessionHolder.hasUser(revision.user); } return { validateRecords: validateRecords, validateRecord: validateRecord, usesLimits: usesLimits, }; } The language looks like it has much to like.
- Veedrac 12y agoThe Java code appears to be broken (`validate(records[i])` should be `validate(record)`). Further, Wake does return Record[].any({ r -> return !validate(r); }); shouldn't this be return Record[].all({ r -> return validate(r); }); ? And the inequality seems to be strict in Wake's case but weak in Java's. Finally, Java won't always return from `validate`. The Java would really benefit from the newest version. I'm no Java expert, but I think it would look a bit like: public class RecordValidator { public RecordValidator(SessionHolder mySessionHolder) { sessionHolder = mySessionHolder; } protected SessionHolder sessionHolder; public boolean validate(List<Record> records) { return records.stream().allMatch(this::validate); } public boolean validate(Record record) { if(record.lastRevision != null && record.lastRevision.user != null) { List<Account> accounts = record.lastRevision.user.getAccounts(); return accounts.stream().allMatch(sessionHolder::hasAccount); } record.revisions.stream().filter(this::usesLimits).count() < 3; } public boolean usesLimits(Revision revision) { return sessionHolder.hasUser(revision.user); } }
- michaelfeathers 12y agoIt's great to see seams thought of at the language design level.
- loop2 12y agoTypes-as-variables is a very good insight. When I'd write C++ function headers where I could omit parameter names without losing any clarity, it'd feel really nice, but the implication never rose to consciousness.
- agumonkey 12y agoClass as interface seems such an obvious thing to do.
- danielscrubs 12y agoSometimes I just have to remind myself that not everyone is from academia. It seems like a great language but where is its charm? It does lot's of small things correct but will it make me think differently? If not it has to get a huge following with every library under the sun (think python or C#) for me to even consider it.
- PSeitz 12y agoConcise: "every RecordValidator is" I would expect a loop here not a declaration.
- juhq 12y agoAnd now we wait for the job ads to roll in. "5 years experience in wake language"
- dajoh 12y ago> We've both created and borrowed some cutting edge ideas. What ideas are new? I'm not sure about provisions because the examples aren't really clear, but all the other features I've seen in other languages before. > 3. Shadowing (concise, safe) It doesn't seem like shadowing is the feature here, rather the use of '$' to prevent shadowing. > Lists (called Arrays in many other languages) There's a very good reason for this. Lists and arrays are very different data structures. Why create confusion by calling them lists? > Since Wake blurs the line between variables and types, we can boast the smallest foreach loop of any language. Really, the smallest foreach loop of any language? Come on. > Self Executing Why is this called 'self executing'? Also, I'd expect any language with lambdas to support calling a lambda right after it's created.