HNHacker News
TopNewBestAskShowJobs

pufuwozu

3,196 karma · joined March 18, 2009

http://www.hackernewsers.com/users/pufuwozu.html

Brian McKenna

http://brianmckenna.org/

http://twitter.com/puffnfresh

Senior R&D Engineer at Precog.

submissionscomments
pufuwozu··on Architecture diagrams should be code
The article has nothing to do with Haskell, other than it's what I use. Why should I have to justify that when I want to talk about architecture diagrams?

Would the same expectation be in place of my examples were in JavaScript? I doubt it.

pufuwozu··on Architecture diagrams should be code
Oh are you intimately familiar with Atlassian's systems?

Marketplace is Atlassian Marketplace, a real website, REST API and bunch of frontend components. If it's not part of an architecture, what is it?

I did simplify Commerce, the system is Atlassian Commerce Cloud Platform. I apologise that I simplified the name for an example, which has confused you.

pufuwozu··on Architecture diagrams should be code
I've used it a bunch. It's pretty good! I think the Java API could use more types and less mutation but it works well.
pufuwozu··on Architecture diagrams should be code
I don't often show architecture diagrams to non technical people BUT I also definitely don't show most technical people this Haskell code. I also don't show them the PlantUML.

I show them the png image.

pufuwozu··on Architecture diagrams should be code
Atlassian Marketplace's architecture diagrams change constantly. Altassian replaces a core system, we have to integrate with a new one, we rewrite or replace a system.

Did you read the part about generating diagrams from different things, e.g. service descriptors, service proxies, tests?

pufuwozu··on Architecture diagrams should be code
I didn't mention it, but I do write architecture diagrams which have input.

    data Version = Current | Future

    generate :: Version -> Diagram
Implementation uses a few if/else expressions. Really simple.

The final points of the post was that we should be able to generate architecture diagrams from other code. Parsing a service descriptor, generating them from tests, etc. You DO need a programming language.

pufuwozu··on Try Idris
Hey everyone, I'm the creator!

Sorry for the problems - I was hotlinking to the awesome http://rawgit.com/ website during development and forgot to remove it before posting it on Twitter.

The website should be fixed in just a few seconds. Thanks for trying it out!

pufuwozu··on Precog is being open-sourced
No processing necessary. Just upload JSON.

The Quirrel language is much more high level than the API for ElasticSearch. It comes with things like machine learning (e.g. clustering and linear regression):

http://precog.com/developers/how-tos/machine-learning/

Even without libraries like machine learning, you can write somewhat readable queries which do some impressive things:

http://precog.com/developers/how-tos/common-analytics/

pufuwozu··on Precog is being open-sourced
I worked on Precog. Here's my explanation:

It's an analytics platform for big data. Basically, you upload lots of JSON, use the custom language (http://quirrel-lang.org/) for analytical queries and the platform will handle efficient storage and querying of your data.

There are also has extras like a library for charting and reporting query responses using JavaScript and an IDE for writing Quirrel and uploading data.

pufuwozu··on Where TDD Fails
TDD increases the chance that more people will mock

Absolutely false. Try TDD in Haskell. Know how many mocking libraries there are in Haskell? None. Totally unnecessary.

pufuwozu··on Where TDD Fails
It's too slow. Now what?

You have to use asymptotic analysis to figure out that it's O(n^3) but can actually be performed in O(n) - then write the derived code from your analysis. Nothing has changed.

Customers care; transitively.

pufuwozu··on Where TDD Fails
Author here. I use Haskell for a lot of webapps. Here's a webapp that talks to GitHub:

http://licentious.herokuapp.com/

https://github.com/pufuwozu/licentious

Here's a programming language competition that I organise:

http://www.pltgames.com/

The web framework that I use is Yesod. Over the years I've used CakePHP, Django, Rails, Lift and Play! - Yesod is definitely the BEST framework I've used:

http://www.yesodweb.com/

pufuwozu··on Where TDD Fails
Did you read the conclusion of TFA?

> Analysis is the method for writing code that satisfies our constraints. Neither TDD nor types are the single answer to writing code that does what we want.

pufuwozu··on Where TDD Fails
Author here. Sadly our WordPress didn't have caching enabled so here's a Gist of the content:

https://gist.github.com/pufuwozu/5095510

pufuwozu··on Leaving Microsoft
From what I can tell, Bryan mostly works in Python and C at Facebook.
pufuwozu··on Meet the new Light Table
Even GHC's (Haskell) REPL executes side-effects.
pufuwozu··on Escape from Callback Hell: Callbacks are the modern goto
Exactly. The promises spec defines the Promise monad. The problem is that JavaScript doesn't have monadic syntax, which would make the code a lot more readable.
pufuwozu··on Escape from Callback Hell: Callbacks are the modern goto
As a creator of an "altJS" language, I've been thinking about this for a long time. I wanted a VM in the browser for years and was a huge fan of Silverlight/Moonlight but I recently changed my mind.

Higher level languages are easier to optimise for. Creating a bytecode would also mean another backwards compatibility hell and another format is not as general as people would like.

pufuwozu··on Escape from Callback Hell: Callbacks are the modern goto
There's a way without exceptions. Use an ErrorT[Promise[A]] monad. I've done this in Scala before and it is so much simpler than the JavaScript convention you pointed out.

It allows you to write code like this:

    val query = "Brian"
    val result = for {
      db <- connectToDatabase
      user <- userFromDatabase(db, query)
      friends <- friendsFromDatabase(db, user.friends)
    } yield friends
Whenever one of the functions above returns an error, the whole expression is that error. The outcome is either an error (if there was any) or the end value of Set[User]. No need to manually handle an error until you get to the end result.
pufuwozu··on Escape from Callback Hell: Callbacks are the modern goto
Thank you. It's really quite depressing to visit Hacker News and see it filled with people being unopen to intelligent ideas to make things better.
pufuwozu··on Escape from Callback Hell: Callbacks are the modern goto
Yes. Elm is a FRP language that compiles to JavaScript. View source on some of the examples:

http://elm-lang.org/Examples.elm

pufuwozu··on Escape from Callback Hell: Callbacks are the modern goto
Callbacks are different than gotos in that they are aren't even remotely close to gotos.

The analogy is that callbacks create non-linear control flow. Using a monadic syntax like in Roy, we can easily have callbacks without having them look non-linear:

    let deferred = {
      return: \x ->
        let d = $.Deferred ()
        d.resolve x
        d.promise ()
      bind: \x f -> x.pipe f
    }

    let v = do deferred
      hello <- $.ajax 'examples/helloworld.roy'
      alias <- $.ajax 'examples/alias.roy'
      return (hello ++ alias)

    v.done console.log
Which compiles into continuation passing:

    var deferred = {
        "return": function(x) {
            var d = $.Deferred();
            d.resolve(x);
            return d.promise();
        },
        "bind": function(x, f) {
            return x.pipe(f);
        }
    };
    var v = (function(){
        var __monad__ = deferred;
        return __monad__.bind($.ajax('examples/helloworld.roy'), function(hello) {
            return __monad__.bind($.ajax('examples/alias.roy'), function(alias) {
                return __monad__.return((hello + alias));
            });
        });
    })();
    v.done(console.log);
Anyway, continuations (with call/cc) are definitely a controlled form of goto. Take a look at an example from Paul Graham:

http://lib.store.yahoo.net/lib/paulgraham/cint.lisp

    ((call/cc
      (lambda (goto)
        (letrec ((start
                  (lambda ()
                    (print "start")
                    (goto next)))
                 (froz
                  (lambda ()
                    (print "froz")
                    (goto last)))
                 (next
                  (lambda ()
                    (print "next")
                    (goto froz)))
                 (last
                  (lambda ()
                    (print "last")
                    (+ 3 4))))
          start))))
pufuwozu··on A Practical Optional Type System for Clojure
That checking is by definition, not type safety.

What you're talking about now is totality. Both Haskell and Clojure allow non-total functions (functions which may not return a result) - the checking that they do are to stop undefined results. Agda is an example of a language that only allows total functions.

pufuwozu··on A Practical Optional Type System for Clojure
type-safety checking is performed at runtime

That doesn't really make sense to a type theorist. The definition of "type-safety" is only applicable statically.

What checking is done at runtime?

pufuwozu··on A Practical Optional Type System for Clojure
I've read a few of Gilad's papers - I just don't see how they can be practical in a world of third-party libraries (e.g. author A hates types, I like type-safety but I have to settle for none when I use that library).
pufuwozu··on A Practical Optional Type System for Clojure
Overall, the work described in this dissertation leads to the conclusion that it appears to be both practical and useful to design and implement an optional static type system for the Clojure programming language.

I'm a huge type safety fan (see http://roy.brianmckenna.org/) so this is pretty amazing. I'm definitely going to play around with Ambrose's work.

Had a quick look, it's really exciting that the algo.monads was almost completely type-checkable with this system.

Leaves me with a couple of questions:

Multimethods are untyped. Anyone able to comment on how often multimethods are used in idiomatic Clojure code?

Anyone know if this work could eventually allow protocols to become full type-classes (allowing dispatch based on return type of protocol methods)? Am I misunderstanding how protocols are compiled?

Hopefully the videos for Typed Clojure at Clojure Conj 2012 will be posted soon after the talk is given :)

My only fear is that optional typing would be less useful than optional untyping. When you have libraries that are untyped, they're a pain to use from a typed language. The other way around is not true.

pufuwozu··on Weekend hack: A little tiled window manager for OS X
I've been using Spectacle for a while and I am working on a port of Xmonad to OSX:

https://github.com/pufuwozu/osxmonad

So I was really interested in trying out this fork. A couple of problems:

* Doesn't look like tiling is automatic, you still have to tell each window which side of the screen to tile on (by using Command+Option)

* I was using it for a minute before it crashed - which I didn't even notice

If those two little problems were fixed I think I could definitely use this until I get my version of Xmonad working properly.

pufuwozu··on Show HN: Matches.js -- Powerful Pattern Matching for Javascript
Sucks that it has to be so stringly typed, but I can't see another alternative.

Multimethods would be an alternative to this type of ad-hoc polymorphism. I've encoded immutable multimethod environments in my new library, bilby.js:

https://github.com/pufuwozu/bilby.js

Lets you write things like this:

    var env = λ.environment()
        .method('length', λ.isArray, function(a) {
            return a.length;
        })
        .method('length', λ.isString, function(s) {
            return s.length;
        })
        .property('empty', function(o) {
            return !this.length(o);
        });

    env.empty([]) == true;
    env.empty([1, 2, 3]) == false;
Where isArray and isString are any functions that return true/false based on the input arguments. The environment then dispatches whichever method that has a predicate return true first.
pufuwozu··on Will Go be the new go-to programming language?
A lot of functional constructs heavily rely on parametric polymorphism. For example:

    map :: (a -> b) -> [a] -> [b]
Interfaces can't provide this type of code reuse.
pufuwozu··on bilby.js - Serious functional programming library for JavaScript
Thanks for the submission! The GitHub repository might be more interesting:

https://github.com/pufuwozu/bilby.js

The syntax examples show off a bit of everything:

Monads:

    λ.Do()(
        λ.some(1) >= function(x) {
            return x < 0 ? λ.none : λ.some(x + 2);
        }
    ).getOrElse(0) == 3;
Kleislis:

    λ.Do()(
        function(x) {
            return x < 0 ? λ.none : λ.some(x + 1);
        } >> function(x) {
            return x % 2 != 0 ? λ.none : λ.some(x + 1);
        }
    )(1).getOrElse(0) == 3;
Functors:

    λ.Do()(
        λ.some(1) < add(2)
    ).getOrElse(0) == 3;
Applicatives:

    λ.Do()(
        λ.some(add) * λ.some(1) * λ.some(2)
    ).getOrElse(0) == 3;
Semigroups:

    λ.Do()(
        λ.some(1) + λ.some(2)
    ).getOrElse(0) == 3;
Page 1 of 8Next →