HN user

gozala

15 karma
Posts0
Comments19
View on HN
No posts found.

Rather than saying that CSP is more general, I'd say CSP is more provides you a more low level constructs. In FRP signals are the key concept that represent value that changes over time. Signals have a pushed based interface that's kind of why it's reactive. FRP typically provides pure functional interface, meaning you never put values or emit events, you just have control flow structures that allow you define transformations over base signals. FRP signals can be easily implemented via CSP channels, but not other way round, that's because CSP channels are push based for the producer side and pull based from the consumer side.

If I had to make an analogy channels would be queues while signals would be an observable variable.

Statement that firefox Add-ons inside the broweser don't have a sandboxing is false. All the add-on SDK built add-ons load in sandboxed in a less privileged JS sandbox, although it is true that there is an escape hatch via `require("chrome")` as some add-ons just want to make modifications that are not even possible elsewhere. This is also reflected on reviews add-ons that do not use `require("chrome")` go through a faster review process while add-on's that do use `require("chrome")` get more thorough reviews.

Your criticism in regards to tooling is valid, but it ignores a bigger picture. Two of the the three different ways of writing add-ons have existed long before chrome was even announced and made great add-ons like firebug possible. The fact that there is already a three different ways to write firefox add-ons is outcome of constant improvement of the firefox add-on platform. While this makes things little confusing for newcomers, it still necessary to keep old add-on systems in place, as this keeps people's add-on's alive and subsequently make users using those add-on happy.

You also misreading blog posts about JPM, as it is not a new official tool yet, but we are working hard to get there. As of reason why, add-on SDK was designed with commonjs modules in mind as we saw it becoming de facto standard. Back then node was not announced yet, needles to mention npm and tons of packages published to it. There for toolchain named CFX was written in python. Now that node became a standard tool in the JS toolchain and npm is where js libraries get published we are working to refresh our toolchain and embrace all this, subsequently making thousands of packages available in npm available to an add-on authors.

I don't think the goal is to replace code entirely, goal is to have a high level tool for high level problem that today is solved with a code but could be lifted. People that love low level stuff will still do it by implementing low level components.

> Of course this means that some of Clojure's features (protocols and lazy sequences, atoms, etc.) are not available. On the other hand there are not so many opaque layers between your code and the target code.

As a matter of fact I plan to provide protocols lazy sequences etc.. in form of (optional) libraries that can be included or omitted based on user use cases. I personally thing that most of these features are drawbacks when interacting with JS code, although I'd definitely used them in cases where interaction with JS is not a concern.

In clojurescript strings are just sequences of characters where characters are expressed as \a and strings as "foo". In JS single char string is an equivalent of a character, as a side effect \a and "a" compiles to a same thing, which BTW matches behavior of clojurescript as well. Main reason for \a like character types existence is clojure(script) compatibility and nothing more.

As of :a keyword it's a different story. As a matter of fact actual (quoted) keyword ':a does not compiles to "a" string, but general references do. That is because in JS constant string literals like "load", "DOMContentLoaded" are used in cases where idiomatic Clojure(script) would have used :load :DOMContentLoaded keywords, there for it made sense to just compile those keywords to semantical analogues in JS, same as `foo-bar` lisp naming convention compiles to adequate `fooBar` naming in JS.

I've tried to elaborate my reasoning in the readme actually:

> Unlike clojurescript, wisp does not depends on JVM and is completely self-hosted. It compromises clojure's awesome data structures and embraces native JS data structures to be a better at cooperation with JS. Goal of wisp is to present a subset of clojure(script) language such that packages written in wisp can be consumed natively by wisp, clojure(script) and JS when compiled, without data marshalling or any code changes.

While I do like clojure(script) a lot I don't think it makes too hard to consume data structures from JS land and makes consuming data produced by clojure(script) awkward for consumption on the JS side. That is a the reasonable compromise for a great power, it's just I think I'd rather leverage JS data structures in immutable manner directly and provide more clojure like data structures in form of libraries. This would allow users to make best (or maybe worst) choices based on their constraints.

As of lispyscript it's nice project and as a matter of fact wisp is just a fork that never got merged in to upstream. I was convinced that clojure (or any other known lisp) syntax was better option than yet another new lisp. In addition I wanted full macros that unlike wisp lispyscript does not has. Also lispyscript has no lists, instead it uses arrays and I can continue this list over and over...

> But why would you want Clojure syntax without Clojure semantics? Especially since Clojure syntax implies several data types that JavaScript can't provide natively. It just doesn't make sense...

JS can do it otherwise clojurescript won't be possible, I just think these data types can be exposed via optional libraries as they have associated cost in terms of performance overhead and learning curve.

And to be quite honest I do hope that a lot of wisp parts will find it's way to clojurescript, it's just contributing to clojurescript turned out to be harder than bootstraping own version, since even pull requests for travis-ci integration tests require lot's of justification.

Yeah I had this comment there // Assuming Mustache.render = promised(Mustache.render)

But my hope is that more libraries will be accepting promises in a future so one won't have to do the wrapping of a world around.

Just to be clear this library implements just a subset of Q with exact same API, with only addition of `promised` wrapper. I'm convinced that this wrapper is a better way to deal with promises than dozens of utility functions that you have to learn about.

For example Q.all is promised(Array) I find later more intuitive.

That's not to say don't use Q! Q is brilliant piece of software and I'd be more than happy to see more people using it.

First of all I implement abstraction using language features and there for I take advantage of it.

  - I favor maintainability over performance, also keep in
  mind that promised function take promises as arguments
  and can't do much until they're fulfilled (associated IO
  is done) so that small performance hit is insignificant
  in most of the cases.
  - You can write your own decorators to wrap constructors
  and their methods if you need to. That being said, I'd
  recommend against, mixing mutable state with logic does
  no good in long run. You'll be better of with functional.
  - As for map / reduce, promises represent eventual values,
  not sequences of them. For that there are streams and I
  have explored that area as well:
  https://github.com/Gozala/streamer/wiki/stream
  I have not wrote about it because I don't think it was
  good idea to dump everything in one post.
I'm happy async did that for you.

What I'm suggesting is that promises don't need any special treatment. If you have a function that you want to feed a promise just wrap it: promised(Mustache.render). That's all it takes.

You're absolutely right! My English is far from being perfect and in addition I was rushing to get this post out making bunch of mistakes. I tried to fix all the "than" "then" issues, thanks for pointing that out ;)

I have already fixed that, it was a typo, I meant following instead:

    var deferred = defer()          // make promise
    var a = deferred.promise
    var b = sum(a, 1)
    var c = sum(b, 5)
    console.log(c)                  // eventually prints => 17
    deferred.resolve(11)            // fulfill promise

You just have to write function per operation that is it:

    var auth = promised(function(user, data) {
      var isAdmin = user.role === admin
      return  isAdmin ? render(open("yay.xml"), db.send(data.request))
                      : render(open("no_permissions.xml"), {})
    })
    
    var puser = getUser(data.session)
    return auth(user, data)

Sorry for confusion, I meant indeed a sync / async APIs. You could easily wrap sync function to give it an async API in order to chain with functions that had async APIs, but it's not really possible other way round (not in JS).