hemanth / functional-programming-jargon

Jargon from the functional programming world in simple terms!
http://git.io/fp-jargons
MIT License
18.59k stars 1.02k forks source link

Added Contracts #127

Closed nickzuber closed 7 years ago

nickzuber commented 7 years ago

Wrote a definition for contracts in programming with an example in ES6. Since there isn't really a way to enforce contracts natively in JavaScript, I tried to write what I thought was a simple example of a way to enforce a contract while still showing what it is exactly. Any suggestions for improvements are welcome!

hemanth commented 7 years ago

LGTM!

jethrolarson commented 7 years ago

:sheep:

hemanth commented 7 years ago

Traversable and Guarded functions remain 👼

jethrolarson commented 7 years ago

I think doing the contracts as a higher-level function would probably be better but this may be easier to understand

hemanth commented 7 years ago

We have #20 to address as well.

nickzuber commented 7 years ago

@jethrolarson Did you see my alternate example?

// Contract Precondition : input -> number
const preconditionsCheck = (input) => {
  if (typeof input === 'number') return true
  throw new Error('Contract violated: expected int -> int')
}

// Contract Postcondition : output -> number
const postconditionsCheck = (output) => {
  if (typeof output === 'number') return true
  throw new Error('Contract violated: expected int -> int')
}

// Contract : number -> number
const runWithContract = (fn, arg) => {
  preconditionsCheck(arg)
  const output = fn(arg)
  postconditionsCheck(output)
  return output;
}

runWithContract(addOne, 2) // 3
runWithContract(addOne, 'some string') //  Contract violated: expected int -> int

This uses more of a HOF approach but is much longer and might not be very concise. Any suggestions?

stereobooster commented 7 years ago

TypeScript, Facebook Flow

jethrolarson commented 7 years ago

I imagine something like:

// spec :: ([a -> Throw | a], (* -> *)) -> * -> Throw | *
const spec = (validators, fn) => (...args) => 
  zipWith(apply, validators, args) && fn(...args)

const add = spec([checkNum, checkNum], (x, y) => x + b)

But again, that's getting rather complex so maybe your solution is better

hemanth commented 7 years ago

yes, to understand what a basic contract is, the merged example is sufficient.

stereobooster commented 7 years ago

Contract, based on this example, is a dynamic type checker. Haskell and C have static type checkers, for instance. But I suppose you can not say that C is programming by contract, right? You need sound type system to call it programming by contract or I miss something?

PS This is amazing project it's just sometimes feel like it oversimplifies some stuff and gives wrong signals. Easy and simple is not the same. For example 3bleu1brown explains complex mathematical subjects simple, but without distortion. See https://www.youtube.com/watch?v=sD0NjbwqlYw.

UPD one more really tiny video on subject of misleading https://www.youtube.com/watch?v=IM630Z8lho8

nickzuber commented 7 years ago

@stereobooster Contracts are more general than just type checking — for example, you can have a contract that promises a function will return a positive integer. While this example does involve a type based contract, I don't really see how it's misleading — I'm sure we could come up with plenty of different examples but we don't want to overwhelm the reader and we want to keep things concise. Also, isn't programming/design by contract a bit off topic in the scope of simply defining contracts? As a side, C can't have a static type checker since C doesn't have a type system — do you mean something else?

I do feel like there could be improvement on the example — feel free to make any suggestions! I found it a little tricky to exemplify contracts in vanilla ES6 without getting too complicated, so improvements are welcome.

stereobooster commented 7 years ago

@nickzuber

Contracts are more general than just type checking — for example, you can have a contract that promises a function will return a positive integer.

Like refinement types? For example in Haskell. Or dependent types like in Idris. Or effectful type system like in F* or Koka.

i :: {ν :int | 1 ≤ ν ∧ ν ≤ 99}

As a side, C can't have a static type checker since C doesn't have a type system — do you mean something else?

Standard C code with types

#include <stdio.h>
int main()
{
    int number;

    // printf() dislpays the formatted output 
    printf("Enter an integer: ");  

    // scanf() reads the formatted input and stores them
    scanf("%d", &number);  

    // printf() displays the formatted output
    printf("You entered: %d", number);
    return 0;
}
nickzuber commented 7 years ago

@stereobooster I was referring to types in the context of a static type system — everything in C is a number in this context. For example, JavaScript is an untyped language but still has primitives like string number object etc

stereobooster commented 7 years ago

Let me be more specific: int number;

Or: int main()

How is that not a statically typed language?

nickzuber commented 7 years ago

@stereobooster Ah I see what you mean — I was thinking about type systems in general in the context of C and how since C doesn't have different values (everything is considered a byte). Just to be clear, you are correct in saying that C is a statically typed language, I got a bit off track here.

Anyways, I digress — if you have any suggestions for improving this example/definition, feel free to post them here!