{ "feed": { "id": "urn:uuid:b48fb060-c28d-5798-9996-f30c6f8d947a", "link": [ { "@attributes": { "href": "\"http://jfolson.com#{current_page.url}\"", "rel": "self" } }, { "@attributes": { "href": "http://jfolson.com/" } } ], "title" : "Problem Solving", "subtitle" : "Algorithms, Programming, Math and Food", "updated" : "2013-04-11T10:36:50-04:00", "author": { "name": "Jamie F Olson" }, "rights" : "Copyright (c) 2013, Jamie F Olson", "entries" : [ { "summary" : "
I had never actually used any of the modern functional programming languages until a couple of weeks ago. However, I\u2019ve worked quite a lot with the functional features of more multi-paradigm languages: python, R, ruby, javascript, etc. so I didn\u2019t expect to be caught off guard by Haskell.
\n", "content" : "I had never actually used any of the modern functional programming languages until a couple of weeks ago. However, I\u2019ve worked quite a lot with the functional features of more multi-paradigm languages: python, R, ruby, javascript, etc. so I didn\u2019t expect to be caught off guard by Haskell.
\nI decided to learn Haskell because I wanted to extend the wonderful Pandoc, which is written in Haskell. This turned out to be a bit more ambitious than I expected.
\nI was almost entirely unprepared for the way Haskell thinks about types. The more functional languages I\u2019ve used have tended to have somewhat weaker type concepts, from the duck-typing of python to the not-really-a-type S3
classes in R.
In contrast, Haskell is strongly typed, and I had not appreciated just how strongly typed it is. To an uninitiated Haskell outsider, I would not have expected types to be a big part of understanding the Pandoc source code. However, in Haskell, types are \u201cmerely\u201d data containers, meaning that any and all containers/structs are new types. This happens because there is no real concept of \u201cmethod\u201d in the object-oriented sense.
\nMaking it worse was the fact that I really did not understand Haskell types. Haskell has completely different concepts for types constructors and data constructors. Types do not actually exist as anything you can refer to in Haskell.
\nf :: FromType -> ToType\ndata FromType = FromTypeConstructor Value
\nHere, you can create an object of type FromType
with FromTypeConstructor value
if value
has type Value
. However, FromType
itself has no value.
This gets particularly complicated since types and constructors have completely separate namespaces! As an example, in Text.JSON
, JSObject
is both a type and a constructor, but the JSObject
constructor does not create JSObject
type objects. Instead, JSONObject
must be used to construct objects of type JSObject
, while the constructor JSObject
creates objects of type JSValue
.
One of the things I\u2019ve liked about git is how much it encourages responsible and clean commits. Personally, I\u2019m not there yet. I commit when I think to, usually when I\u2019m at a reasonable stopping point, which means I just end up doing git commit -a
rather than adding and committing clean groups of related
One of the things I\u2019ve liked about git is how much it encourages responsible and clean commits. Personally, I\u2019m not there yet. I commit when I think to, usually when I\u2019m at a reasonable stopping point, which means I just end up doing git commit -a
rather than adding and committing clean groups of related changes.
Because of this, when I submitted a pull request to the awesome Pandoc, my commit history was a mess. The owner of the project, John MacFarlane, reasonably asked to to separate things into nice clean commits. Embarrassingly, I\u2019d never done this before, but everything went a bit smoother than expected.
\nThe git rebase
command allows you to rewrite the commit history of your project. There are lots of ways to do this, but I found the easiest to be:
git rebase -i HEAD~10
\nWhich will allow you to edit the ten most recent commits.
\nThe git documentation describes how to use this, but I had trouble using the squash
option and just ended up edit
ing them all.
As mentioned there, git reset HEAD^
resets the staged commit and then you\u2019re free to commit as you wish before using git rebase --continue
to move forward.
Implicit conversion with ==
0=="0"
\nBut no unboxing with ===
0!==new Number(0)
\nEquality is not transitive
\n"" == 0 \n0 == "0" \n"" != "0"
\nparseInt is not base ten!
\nparseInt("8"); //8\nparseInt("08"); //0
\n",
"content" : "Implicit conversion with ==
0=="0"
\nBut no unboxing with ===
0!==new Number(0)
\nEquality is not transitive
\n"" == 0 \n0 == "0" \n"" != "0"
\nparseInt is not base ten!
\nparseInt("8"); //8\nparseInt("08"); //0
\nTypes and Objects don\u2019t know about eachother
\ntypeof "hello" === "string"; //true\ntypeof new String("hello") === "string"; //false\n"hello" instanceof String; //false\nnew String("hello") instanceof String; //true
\nPeople use object literals {}
to construct map-like objects, but they\u2019re not real maps! What they actually do is map the string conversion of the object. Look what happens when you try to nest objects inside objects:
> var a = {x:"a"}\nundefined\n> var b = {x:"b"}\nundefined\n> var obj = {}\nundefined\n> obj[a] = "a"\n"a"\n> obj[b] = "b"\n"b"\n> obj[a]\n"b"
\n",
"title" : "Javascript's Nearly Unforgiveable Sins",
"updated" : "2013-03-18T00:00:00+00:00",
"id" : "urn:uuid:458b19f8-85a8-56c5-aad0-c5939daeb593",
"link" : "http://jfolson.com/blog/2013/03/18/javascript-sins/"
},
]
}
}