HN user

barkmadley

94 karma
Posts2
Comments56
View on HN

You probably could, but there would be lots of extra boiler plate that distract from the central idea.

The OCaml language features that are used that would need to be emulated somehow in Java:

* Sum types (type a = A of int | B of float). Think tagged unions [1].

* Module functors (module NAME(PARAM : MODULE_TYPE) = struct ... end). Think package level functions (you get some of this with dependency injection frameworks, but it's probably no-where near as safe/sane and flexible.

* GADTs (type a = A : int -> int | int term). I'm not sure how you would represent these in java, I'm not fully up to speed on how they work yet.

[1] http://en.wikipedia.org/wiki/Tagged_union

I don't know what you mean by this. An Iterable<X,Nothing> cannot return Null from its first attribute. Check the declaration of Iterable.first.

This made me sad again[1], but then this made me happier[2] (internalFirst implied it is defined in the compiler, finding all of the pieces that make up the definition was a bit of a pain since it is dispersed across so many files), but I think I didn't fully understand union types (and that Nothing was bottom) when I wrote the grand parents logical conclusions.

    :t Iterable<X,Nothing>.first ==>
       X|Nothing ==>
       X (because union with empty is an identity)
therefore inside max, the variable first will have type X when given an Iterable<X,Nothing>.first. I also see how it cannot be re-written as I proposed because there is no guarantee that Absent will be of type Null.

That's not correct. Go and check the definition of Null. It's just a regular class, as advertised. There is no special behavior defined in the language spec. Sure, the exists operator is defined by the language spec to mean "is Object", but that's just trivial syntax sugar.

I did check the definition of Null, I was merely pointing out that although it is a user definable type, the language specification does mention its existence here[3] and here[4] which is where I looked to try to find out what the "exists" keyword meant. Specifically:

    in the case of an exists condition, a type whose intersection with Null is not exactly Nothing and whose intersection with Object is not exactly Nothing, or
Later on it says "exists x is equivalent to is Object x, and..." but then why reference Null earlier?

I guess the problem here is that you're used to languages full of weird special cases and ad hoc behavior.

While I thank you for your time answering my mis-understandings of union types, please do not shoe horn me. My main programming activities are using OCaml and Haskell, both of which have very few ad-hoc language features, if any.

[1] http://modules.ceylon-lang.org/repo/1/ceylon/language/1.0.0/...

[2] https://github.com/ceylon/ceylon.language/blob/master/src/ce...

[3] http://ceylon-lang.org/documentation/1.0/spec/html_single/#c...

[4] http://ceylon-lang.org/documentation/1.0/spec/html_single/#a...

I assume this is the implementation [1](took me a while to find the type to see how the compiler might interpret it).

I read the definition as (ignoring the implementation):

    return a Value or Absent when given an Iterable<Value,Absent> where Value is Comparable and Absent is Null
Correct me if I am wrong, but there doesn't appear to be anything linking the nullability of the return value based on the possible emptiness of the input value. How does the compiler check this constraint (which sounds a lot like a dependent type relation)?

Upon further reading of the Iterable type[2], I have more questions, does "Nothing" satisfy "Null"?

| If not, then it looks to me like passing in a non-empty iterable (Iterable<X,Nothing>) is a type error.

| If so then I would imagine that it becomes harder to enforce the constraint, likely because the return type can still be Null regardless of input restrictions. Does this use extra type inference on the expressions inside the function to do the enforcement, for instance using the "exists" operator to perform type set subtraction between {Value|Null} and {Null} on the true branch. This implies that if I re-write the max function to have a single exit point (`ret = Null; if (exists values.first) { ...; ret = ...; } return ret;`) then I don't get the same guarantees?

Also the fact that Null is referenced by the "exists" operator also implies that it is part of the language specification, and not actually definable in any meaningful way as a user type.

Digging a bit deeper, I was very disappointed to read this snippet [3]:

    Nothing is considered to belong to the module ceylon.language. However, it cannot be defined within the language.
If I read correctly, that means that I cannot implement the same behaviour/enforcement with completely user defined types.

[1] http://modules.ceylon-lang.org/repo/1/ceylon/language/1.0.0/...

[2] http://modules.ceylon-lang.org/repo/1/ceylon/language/1.0.0/...

[3] http://modules.ceylon-lang.org/repo/1/ceylon/language/1.0.0/...

> Can I write a method that's polymorphicly nullable?

Sure. You should see the crazily cool stuff we can do with stuff like the signature of max(). You'll be impressed, I promise!

From the docs:

A nonempty iterable is an iterable object which always produces at least one value. A nonempty iterabe type is written {String+}. Distingushing nonempty streams of values lets us correctly express the type of functions like max():

{Float+} oneOrMore = .... ;

{Float*} zeroOrMore = .... ;

Float maxOfOneOrMore = max(oneOrMore); //never null

Float? maxOfZeroOrMore = max(zeroOrMore); //might be null

While this is interesting, is it enforced by the compiler? i.e. is the following a runtime, or compile time error?:

    Float maxOfOneOrMore = max(zeroOrMore);
Workflow in tmux 13 years ago

I would find Caps+a very difficult to type (since it uses the two weakest fingers). Have you ever tried Caps+d or Caps+f?

If I may, the goal seems a bit incorrectly specified for hypermedia. For instance, if github decided to change the number of results they return per page, then your script would not break, but it would have a different meaning.

I would suggest a better goal to be "get the 11th public gist". Although that still isn't perfect since it doesn't mention how the collection would be sorted (I presume by date).

You can implement crons level of timing specificity with a few "every" jobs and some variables.

e.g. (not real syntax)

    every minute: set minute = (minute + 1) % 60

    when minute = 4 && day = 5 ...
I think the better part of this system is the cascading success semantics that it would provide, where by a next stage doesn't start if the previous stage didn't finish successfully. This has a lot of overlap with Jenkins and other CI servers, but without the java/http overhead and with a (potentially) lighter weight text based syntax for specifying the dependencies between jobs.

I can even envision this sort of system to be used to distribute jobs to slave machines given a small amount of ssh foo.

I think the simplicity comes from being able to learn each piece in isolation, without any loss of generality. In addition, once each piece is learned, it does not need to be used in isolation, meaning each piece learned multiplies the abilities of the learner, as opposed to merely adding to it.

I think the difference would be that TomTom supplies it's own maps in the App, whereas Google Navigation probably downloads the tiles/street view as you go.

This can make a world of difference when travelling abroad when you can't be bothered getting a local data plan.

I definitely use GPS navigation more often when travelling than when in my home country.

    and it makes sense that static analysis tools won't discover anything not already covered by tests
That assertion doesn't make a lot of sense to me. Most static analysers are capable of looking at the edge cases that a human may forget to write a test for, or may not even notice are there.

Of course not. At least not yet. The only missing piece is to bind the data that is already found in the html to the data found in the view-model object (or create the view-model object from the html, or some third strategy). This has been suggested a couple of times on the mailing list, but no-one has stepped up to the plate to implement it.

actually the attribute syntax leaves a lot to be desired in terms of redundancy. First you have to quote the attributes (or put a : in front of them?), yuck. you need to use the => operator which is two times too big, and whats with the unnecessary outer braces?

non-idiomatic hamlet isn't far from that haml snippet (note you would never put bits of urls in the template as strings, instead you provide a url rendering function which converts the @{} bits into url strings):

    <#gallery
      <.screenshots
      <ul
        <li
          <a href=@{View first}
idiomatic hamlet is much more focused on being a cleaner html for designers than it is trying to be a haml clone.

Yes, knockoutjs doesn't have it's own validation rules. Yes knockoutjs doesn't have routing. Yes, knockoutjs doesn't have ajax helpers.

In all these frameworks that add those features, they forgot to copy two that I personally love to death. data bind attributes can contain arbitrary javascript, and creating new types of data bindings is insanely trivial.

For me, the new operator (in javascript) is an optimisation, so it should be inserted into a code base after profiling. In accordance with the "make it work, make it right, make it fast" philosophy of development.

The desugaring process is what makes the for loop magic. I cannot write a different control structure that looks like the that for loop in scala without touching the compiler.

A counter example that shows how to avoid the sugar would be "if expressions" in smalltalk (simplified, may differ to reality). In smalltalk, the abstract boolean class has a method 'if'. And the "true" subclass of the boolean class implements the 'if' method to execute its first parameter, while the "false" subclass implements the 'if' method to execute its second parameter.

Why not have both? Also do you happen to use any regular expressions ever? Can you imagine specifying a regular expression using self-explanatory alphanumeric method names?