jsigbiz / spec

JavaScript signature notation
130 stars 6 forks source link

Examples of projects using jsig #5

Open junosuarez opened 11 years ago

junosuarez commented 11 years ago

I created a wiki page for projects using jsig - please feel free to try it out and add your own.

Raynos commented 11 years ago

I started using it here https://gist.github.com/Raynos/b8bf27d5d05811858bfc#file-continuable-js-L10

Now sure how to make partial more readable.

junosuarez commented 11 years ago

Thanks for sharing!

// partial (fn: Function, ...args: Value) => Function
// map :: (lambda:(A) => B) => (Continuable<A>) => Continuable<B>

Here, just to clarify, what is the intention of using :: on map but not on partial? In the draft spec, the above version would annotate the named function, and the below is unspecified (although I have seen the :: notation used elsewhere to associate a type with a function name)

// fileName := Continuable<[String]>
var fileNames = partial(fs.readdir, __dirname)

This is an interesting annotation case, which I read as a prolog-style declarative assignment. I guess I would read it as "fileName becomes a Continuable of a 1-element tuple of a string" (although in the context of fs.readdir it looks like it would be a Continuable<Array<String>> - see Arrays in Generic Types and Tuples - if you'd like to discuss typed-array-literal notation, please open another thread)

My question is: is it valuable to have name := type notation distinct from name : type? If so, can we clarify what this means semantically?

Raynos commented 11 years ago

@jden I forgot to remove :: when I ported it from Haskell style.

I also forgot to port [String] to Array<String>. I like the idea of having [String] as short for Array<String>

I have used name : type to say the name is of this type when used as a type in either return or function arguments.

I haved name := type to say the local variable named name is of this type in the code.

So : is for defining custom types. := is for making it obvious what the types of local variables are without having to remember what multiple applications of map and flatten return.

Raynos commented 11 years ago

@jden another example of jsig being used https://github.com/pufuwozu/fantasy-land/issues/16#issuecomment-16326928

Raynos commented 11 years ago

@jden I wouldn't mind using :: after a function name to make things more readable.

// map (lambda:(A) => B) => (Continuable<A>) => Continuable<B>
// map :: (lambda:(A) => B) => (Continuable<A>) => Continuable<B>

I find the latter more readable because your saming the function declaration named map has this signature. The former just uses a space seperator which is not as obvouis

Raynos commented 11 years ago

@jden having thought about it more. I think having := : and :: is confusing.

Maybe just : and := is enough. One declares types. The other declares signatures of values in the program. Of course the absence of either operator can still be used to mean := but I don't like that.

junosuarez commented 11 years ago

@raynos

So : is for defining custom types. := is for making it obvious what the types of local variables are without having to remember what multiple applications of map and flatten return.

I like this, it's useful for inline comments, especially in short code examples, gists, etc. Care to take a crack at writing it up in a PR?

I agree that having : and :: can add confusion, or at least noise. Unless there's clear value in distinguishing them, I'd rather pick one and go with it. The : can be read as "is a", for example, "map is a function with parameters ... which returns a ..."

As currently written, the draft allows for a named function to be specified either with or without a :. Whitespace is optional throughout.

Raynos commented 11 years ago

Alternative proposal. Get rid of : to mean "declare this name to be a certain type" : is already overloaded in object declarations for key:value.

Instead have

// type Continuable<T> := (continuation:(err: Error, result: T) => void) => void
// map := (lambda:(A) => B) => (Continuable<A>) => Continuable<B>
junosuarez commented 11 years ago

The appeal of having : at the top level is that it's just a composition of the same meaning within a type declaration (for named parameters and object properties), and that it's a symbol already in JavaScript. I'd love to get @kitcambridge's opinion here re : vs :=

Raynos commented 11 years ago

Here are some more examples from some internal code.

/*
    See question.js for Question & QuestionLevelType

    type SetScore := { completed: Number, correct: Number }
    type Answer := {
        questionId: String,
        selectedAnswer: Number,
        isCorrect: Boolean
    }
    type QuizState := {
        questions: [Question],
        answers: [Answer]
        score: {
            "Youngling": SetScore,
            "Padawan": SetScore,
            "Jedi Knight": SetScore,
            "Jedi Master": SetScore,
            "Jedi Grand Master": SetScore
        },
        currentSet: QuestionLevelType | "Completed"
    }
*/

// QuizState := (Array<Question>) => QuizState
function QuizState(questions) {
    ...
}
/*  see question.js for QuestionLevelType

    type RangeCondition := {
        type: QuestionLevelType,
        is: "rangeCondition",
        minimum: Number,
        maximum: Number
    }
    type SizeCondition := {
        type: QuestionLevelType,
        is: "sizeCondition",
        size: Number
    }
    type TransitionCondition := RangeCondition | SizeCondition

    transitions := Object<QuestionLevelType, {
        conditions: Array<TransitionCondition>,
        target: QuestionLevelType,
        level?: String
    }>
*/
var transitions = require("../data/transitions")

// transitionSet := (QuizState, String) => QuizState
function transitionSet(quizState, completedSet) {
    ...
}

I like the ability to go type foo := bar | baz. I also did is: "rangeCondition", to say its a string and very specifically that very string.

Also note I do Object<QuestionLevelType, { ... } where QuestionLevelType is an Enum<String> to say that it's an object with very specific keys and not arbitrary keys

Raynos commented 11 years ago

I added an examples folder to my fork

I will also edit the README soon to update it with a bunch of changes.

Raynos commented 10 years ago

I will do a search for all my docs.mli and add them to the wiki soon :)