Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to ES6 | ES2015 #235

Closed
wants to merge 11 commits into from
Closed

Update to ES6 | ES2015 #235

wants to merge 11 commits into from

Conversation

christiantakle
Copy link
Contributor

  • Chapter 1
  • Chapter 2
  • Chapter 3
  • Chapter 4
  • Chapter 5
  • Chapter 6
  • Chapter 7
  • Chapter 8
  • Chapter 9
  • Chapter 10
  • Write tests for all examples or make all examples runnable?

I think we should update the text and provide a better OOP example. The code is still very verbose. We could also keep the current mutating code and just call it imperative instead of OOP.

class Flock {
  constructor(n) {
    this.seagulls = n;
  }

  conjoin(other) {
    return new Flock2(this.seagulls + other.seagulls);
  }

  breed(other) {
    return new Flock2(this.seagulls * other.seagulls);
  }
}

Based on: https://gist.github.com/eshacker/be153d852b9b995f42dd

@christiantakle
Copy link
Contributor Author

I havn't updated var. Do we prefer let or const?

I remember an article about one complaining about the use of const when debugging in chrome dev tools :)

Anywho just need guidance on preferred coding style and then I will update the rest.

@gabrielflorit
Copy link

@christiantakle
Copy link
Contributor Author

@gabrielflorit I'm not sure what it is you want me to see, #83 was mentioned in my other PR and it doesn't seem like there is any conclusion.

Nothing is holding us back from turning this branch into an ES6 version of the book. I just wanted to start doing actual work.

@KtorZ
Copy link
Member

KtorZ commented Jan 7, 2016

let and const has different meaning.
const semantically describe a piece of data that should remain immutable because of it's essence. I mean, doing pure functional, all your data are supposed to be immutable and in a way, you're not supposed to declare variable at all :| (except for the ones holding functions we're using ^.^)

Using const and let is more a matter of meaning that anything else. At the end, even using const, your variable is still mutable. const just means that you won't do any other assignation to that variable (you won't be able to though).
To me, the meaning is close to the difference between a reference / pointer, and a value we could find in other language. If your intent is to change the value held by the variable, then declares it with let. Otherwise, if your value just reflects a statement one may assume as always equals to the value with which it has been initialized such that no one is ever supposed to change that variable at runtime, then use const.

Cheers.

@Lichtjaeger
Copy link

There is a little bit more. Even var has still legitimacy.
There is a good article in You-Dont-Know-JS.
(And espacially a section about using const or not)

@gabrielflorit
Copy link

Oh I see @christiantakle - didn't notice you were already aware of #83.

@christiantakle
Copy link
Contributor Author

@KtorZ @Lichtjaeger

I think const make the most sense in most of our cases.

What do you prefer?

const fn1;
const fn2;
const fn3;

// vs

const
  fn1,
  fn2,
  fn3;

Personally I remove as much syntax as I can so I'm biased. I will just do what the majority like.

@kwijibo
Copy link
Contributor

kwijibo commented Jan 8, 2016

I think it would be nice if the style was consistent with the es6 code in @DrBoolean's Prof. Frisby videos, eg: https://youtu.be/oZ6C9h49bu8?t=10m36s

uses const, no terminating semicolons, and a const keywork for each variable:

const Point = Number
const Url = String
@christiantakle
Copy link
Contributor Author

@kwijibo excellent proposal. I will follow that style for starters.

@Lichtjaeger
Copy link

I agree with @kwijibo. It also corresponds to the "JS Standart Style"-initiative.

@christiantakle
Copy link
Contributor Author

Lichtjaeger 👍

I need to think about how I handle extensions of class. Its quite ugly to mix that and prototype. It might be best just to declare the entire class every time.

Its a bit problematic in chapter 10 since its shown how map can be derived from chain and ap from map/chain

After that I will update enviroment for readers to play/test the code.

show = post => Views.show(post),
create = attrs => Db.create(attrs),
update = post => Db.update(post, attrs),
destroy = post => Db.destroy(post);

return {
index: index, show: show, create: create, update: update, destroy: destroy
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why about using object property shorthand here :) ?

return { index, show, create, update, destroy }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, I will update that

@KtorZ
Copy link
Member

KtorZ commented Jan 12, 2016

Nice job so far @christiantakle 👍
Question for you guys:

What about taking advantage of the import/export and destructuring features offered by es6... In a way, that could make the examples more concise and clearer whereas we loose the explicit dependency reference :/
For instance, looking at the following:

const mediaUrl = _.compose(_.prop('m'), _.prop('media'))
const mediaToImg = _.compose(img, mediaUrl)
const images = _.compose(_.map(mediaToImg), _.prop('items'))

We can end up with something like this:

import { compose, prop, map } from 'ramda'

const mediaUrl = compose(prop('m'), prop('media'))
const mediaToImg = compose(img, mediaUrl)
const images = compose(map(mediaToImg), prop('items'))

Not a huge change but I'd rather like the second form though.

@alistairstead
Copy link

If using ES2015 syntax then this makes the example clearer IMO. 👍

@christiantakle
Copy link
Contributor Author

I'm thinking of going this way as you can see here: https://github.com/MostlyAdequate/mostly-adequate-guide/pull/235/files#diff-eca58e722edd3254515254f62175aac0R130

Consistency is my most important goal, so most changes are currently partial/rough. I will iterate over everything again to polish rough edges.

I'm writing Haskell at my everyday work and in bigger examples its actually nice to important functions qualified since many of them have the same name. Its different in Javascript though.

@christiantakle
Copy link
Contributor Author

Short update, sorry for being busy. I will start working on this PR again.

Cheers

@thurt
Copy link
Contributor

thurt commented Apr 26, 2016

@christiantakle

I need to think about how I handle extensions of class. Its quite ugly to mix that and prototype. It might be best just to declare the entire class every time.

Its a bit problematic in chapter 10 since its shown how map can be derived from chain and ap from map/chain

If I follow you correctly: I think it makes sense to just create a separate class for each functor, applicative, and monad. It seems like using class extends might be obfuscating to someone who is still trying to learn how the base class works. Also consider, the book doesn't really show the whole picture about how these classes can be derived from each other until late in the book, chapter 10, like you mentioned.

@christiantakle
Copy link
Contributor Author

@thurt Thanks for the input that makes a lot of sense. We can take inspiration from the Purescript refinements of the Haskell type classes.

http://blog.functorial.com/posts/2015-12-06-Counterexamples.html, see The Monad Hierarchy

@thurt
Copy link
Contributor

thurt commented Apr 27, 2016

@christiantakle I just finished the book yesterday and haven't programmed in FP style before. So I am having trouble understanding some of the type signatures and logic in the link you provide--I may not be much help beyond this.

My main impression from the contents of the book:

  • a functor type must have a map
  • an applicative type must have an of/ap
  • a monad type must have a chain

of/ap can be derived from chain
map can be derived from of/ap

@christiantakle
Copy link
Contributor Author

@thurt Its very insightful input I've been doing it for a while so I can accidentally make things harder than its need to be.

Your basic intuition is correct, however its important that the implementation follow some laws e.g.

Functor laws

map id        = id
map (f . g) = (map f) . (map g)

Aside

The hierarchy is:
A Monad must be an Applicative Functor
An Applicative Functor must be a Functor
See https://wiki.haskell.org/File:Typeclassopedia-diagram.png

Which is the reason you can derive them from each other e.g.

chain = (m,f) => join( map(f,m) )
map   = (f,x) => chain(x,(compose(of, f)))

Taken from https://en.wikibooks.org/wiki/Haskell/Understanding_monads#Monadic_composition

This was referenced May 2, 2016
@christiantakle
Copy link
Contributor Author

#273 revives this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
7 participants