jawher's comments

jawher | 8 years ago | on: Using Go for Scalable Operating System Analytics

Thanks for citing mow.cli [1] and glad you're liking it!

And you are spot-on regarding closures: it was a design choice made expressly for the purpose of being able to:

- scope command specific flag and args, instead of having one giant catch-all context map

- declare real and typed Go variables instead of something like context.String("--option")

- use the same pattern as the flag std package (flag.Bool, etc.) which I liked a lot

Disclaimer: I am the author of mow.cli

[1] https://github.com/jawher/mow.cli

jawher | 11 years ago | on: Parsing command line arguments using a finite state machine and backtracking

docopt() does few things and does them well:

* parse the call arguments and split them into options and arguments

* perform a very basic validation, i.e. handle the options which take a value and those who don't

Granted, mow.cli is much more complex. But it also does much more:

* Generate contextual help message

* Enforce arbitrarily complex validation rules (see the cp example) in your stead, meaning less code (and bugs) for you to write

* Does the routing, i.e. you don't need to have multi-level switch/case and if/else blocks to select and execute the correct code path based on the input arguments.

I talked about this in a previous article [1].

And finally, the library user doesn't have to deal with all this complexity: this is an implementation detail which I thought would interest technical readers, hence blogging about it.

You as a user only use the much easier to grasp exposed API [2]

[1] https://jawher.me/2015/01/13/parsing-command-line-arguments-...

[2] http://godoc.org/github.com/jawher/mow.cli

jawher | 11 years ago | on: Parsing command line arguments using a finite state machine and backtracking

Parser combinators would certainly have been easier for me, the library author but not necessarily so for the end user.

Contrast how it is done now:

  [-R [-H | -L | -P]] [-fi | -n] [-apvX] SRC... DST
With a parser combinator based approach:

  and(
    optional(and('-R', or('-H', '-L', '-P'))),
    optional(or(
                '-fi', 
                '-n'
             )
    ),
    optional('-apvX'),
    repeatable('SRC'),
    'DST')
And this didn't even handle the fact that options order is not important.

jawher | 13 years ago | on: Twitter survives election after Ruby-to-JVM move

> Nice hand-waving of an argument, by throwing a useless Wikipedia link in there as some kind of appeal to authority

No need to get agressive over this :) I disagreed with your first comment regarding the dynamic nature of the JVM, and replied trying to explain why.

I posted the wikipedia link not as kind of an "appeal to authority", but to give the readers a full listing of bytecode instructions, so that they can check what I was saying for themselves.

> Disregarding primitives, the JVM doesn't give a crap about what types you push/pop the stack or what values you return.

It depends how you see things: the JVM can't possibly provide instructions for every possible user type, so apart from primitives, the other object types are passed around as pointers or references, but whenever you try to do something other than storing/loading them on the stack, the type checking kicks in, ensuring that the reference being manipulated has the right types.

For instance, the putfield instruction doesn't just take the field name where the top of the stack is going to get stored. It also takes the type of the field as a parameter, to ensure that the types are compatible.

Constrast this to Python's bytecode, where the equivalent STORE_NAME (or the other variants) doesn't ask you to provide type informations.

But then again, we might be splitting hairs here: since this type checking is happening at runtime (when the JVM is running your code), you could indeed question calling it "static typing", which is usually performed at compile time (an is partially performed by the java compiler for example).

jawher | 13 years ago | on: Twitter survives election after Ruby-to-JVM move

> The JVM, at its core, is not working with static types. The bytecode itself is free of static types, except for when you want to invoke a method, in which case you need a concrete name for the type for which you invoke that method ...

Not sure what gave you this impression, as the majority of Java bytecode instructions are typed. For example, the add instruction comes in typed variants: iadd (for ints), ladd (for longs), dadd (for doubles), fadd (floats), etc.

The same is true for most other instructions: the other arithmetic instructions (div, sub, etc.), the comparison instructions (*cmp), pushing constants on the stack, setting and loading local variables, returning values from methods, etc.

http://en.wikipedia.org/wiki/Java_bytecode_instruction_listi...

InvokeDynamic, as you point it out, was added to make implementing dynamic languages on the JVM easier, because the JVM was too statically typed at its core.

jawher | 13 years ago | on: Mono 3.0 is out

> BUT that is happy to let you write a Windows program or a Mac program or a Linux program if that's what you want.

Care to explain the last bit ? Because Java also lets you invoke native code (and hence platform specific) if you want to.

jawher | 14 years ago | on: What else is new in c# 5

Is it just me or does anybody else think that polluting your code with debugging and logging informations is not such a good idea ?

I understand the value of these informations, but changing your method signatures to take them is going too far in my opinion, especially that there a a less obtrusive ways to achieve the same functionality: stack traces. I'm a Java developer, so I don't know the equivalent in C#, but in Java, you can get the stack trace (or call stack) of the current thread:

    Thread.currentThread().getStacktrace()
Which will return an array containing all the info you'd like, with method names, line numbers and file names.

jawher | 14 years ago | on: What else is new in c# 5

> Maven is a bad dependency/package manager because of the complicated nuance

What nuance ?

>XML

Fair point. I don't know what they were thinking when they decided not to use attributes, but come on, XML is not that bad.

> Java 8 is even planning on using Project Jigsaw to get rid of it (IIRC).

Wrong: Jigsaw is a modularity tool, maven is a build tool. Jigsaw is intended as a competitor to OSGi, not maven. Jigsaw won't compile your project, resolve your dependencies nor deploy your product.

> Something like Grape or Buildr would be a better model.

I beg to differ. I'm no big fan of maven either, but the idea behind it is pure genius, i.e. an implicit source layout and build lifecycle. Where in imperative tools like ant and co you'd need to repeat again and again the same snippets, compile all those files in the src dir into a bin dir, copy a bunch of resource files to the bin dir, package the whole thing in a jar or a war, place it in a target dir. Also, the dependencies management used to be a tedious task, with you hunting for the correct versions of jars, placing them in a lib directory, going as far as to version them. Most tools now tend to emulate maven's way of dependency management.

Nothing like this with maven: you just place your code and resources in standard locations, create a pom.xml file with just infos regarding your project (name, version and type), possibly the dependencies, and with standard commandes (mvn install for example), it will fetch the dependencies, build your porject, package it and install it.

Maven has its warts: verbose XML, unexpected behaviour in some cases, hard to customize (mostly when you try hard not to follow the standards), etc. But these are minor and fixable issues compared to the value it provides to countless developers who could fetch a project source and build it with one standard command.

jawher | 14 years ago | on: Roy — small functional language that compiles to JavaScript

Can't you take te same approach ClojureScript took, i.e. to generate a straitforward translation to JavaScript, and then let Google's closure compiler take care of the optimizing thing ?

For instance, for this Roy generated JS:

    var True = function(){};
    var False = function(){};
    var getBool = function(b, ifTrue, ifFalse) {
        return (function() {
            if(b instanceof True) {
                return ifTrue;
            } else if(b instanceof False) {
                return ifFalse;
            }
        })();
    }

The Closure compiler generates:

    var True = function() {
    }, False = function() {
    }, getBool = function(b, c, d) {
      var a;
      b instanceof True ? a = c : b instanceof False && (a = d);
      return a
    };

jawher | 14 years ago | on: 11 Amazing Things NASA's Huge Mars Rover Can Do

While I share your enthusiasm, I'd like to point out some problems with "Sending rovers to all the planets": 4 of them are gaseous giants, literally no solid ground to land on. Venus is a no go too with its crushing atmospheric pressure, sulfuric acid clouds and 400+ c° temperatures.

jawher | 14 years ago | on: ORM is an anti-pattern

That depends on what kind of products you make: If it's a website, then you have absolute control over what stack and database to use. But if you're selling any kind of app that needs a database, then you'll need to support different databases. Some customers won't ask questions and take your default database, others (unfortunately ?) will want it to use their Oracle/SQLServer installation that cost them a bazillion.

jawher | 14 years ago | on: ORM is an anti-pattern

It's not just the SQL. There's also the mapping code between your objects and the SQL. for instance, for a select query:

    select first_name, last_name, login, email from users where id = 5;
Depending on the language and ORM you use, you'll need to write code that resembles this:

    result = execute(query);
    User u = new User();
    u.firstName = result.get("first_name);
    u.lastName = result.get("last_name);
    u.login = result.get("login);
    u.email = result.get("email);
The mapping part may also involve data conversion between SQL types and you language types.

The same also applies to the other direction: when you want to generate an SQL query that updates/inserts an object of yours into the database.

ORMs also handle (I didn't say well) relations between objects (1..1, 1..n, n..n).

jawher | 14 years ago | on: ORM is an anti-pattern

  > This doesn't seem like an insoluble problem; rather than use an ORM to generate an impenetrable glue layer, it would be better to use code generation tools to create a clean database model and a glue layer that can be easily overloaded as required.
Glad you brought that up. I too thought about this as a middle ground solution between "boring your self to death by writing dozens of SQL queries and hand mapping to your model" and "black box ORM that generates crazy SQL queries".

I'm not sure it would work though. One of the problems I see is inherent with code generation approach: what happens when you had to modify the generated code and then changed your meta-model and want to regenerate the model again ?

Besides, the problem of "fitting square pigs in a round hole" would remain: SQL is much more versatile and flexible than objects/structs: you simply can't just work with the a table=an object abstraction, which tends to yield inefficient database queries and/or headaches from the developers side. Example:

    update table set one_field=value where some_condition_on_another_field.
How would you expect an ORM to generate a "dense" query like this with it's simplistic view of things ?

The same applies for the select queries, especially for reporting and data aggregation needs, where you would select some columns from multiple tables, possibly with formulas and computed columns.

jawher | 14 years ago | on: ORM is an anti-pattern

It depends on the ORM you use, but I'm afraid it's not as simple as "you can later hand write SQL queries to speed things up". This will interact badly with the ORM's cache/transaction handling: your select queries won't see uncommitted changes held by the ORM, and even worse, your ORM won't see the modifications you made with insert/update/delete SQL queries.

Also, one of the pro ORM arguments is that it generates database-specific SQL, making your code theoretically portable between different RDBMS. Hand writing SQL will break this.

Another point: your ORM would automatically pick up changes to your model and cope with it, not your hand-written SQL, making your code harder to maintain.

jawher | 14 years ago | on: Why Arabic is Terrific

> The structural change is regular. That is you don't have to learn each name plural.

Not all the time. And if they do, there still are subtle variations in suffixes. For example:

- Kalb (dog) => Kilab (dogs)

- Liss (thief) => Losous (thieves)

- Karoura (bottle) => Kawarir (Bottles)

- etc.

> I thought the same thing for English and French, no? When I learn English and French in school, we join letters.

Yes, but that doesn't change the letter's shape as in Arabic, you just add a line to connect letters.

> The same for french. (Il, Ils, Elle, Elles, On)

Not quite: what you cite are just pronouns, but the conjugation and grammar doesn't vary. For instance, conjugating the verb manger (to eat) with feminine plural "elles" and masculine plural yields the same "mangent", whereas in Arabic you have different forms.

> Not true. The real Arabic numbers are the ones used today. The Indian numbers were used in the middle east region because of the strong Indian influence.

Agreed. I myself have a hard time reading numbers written in the Hindi numerals (٠‎ - ١‎ - ٢‎ - ٣‎ - ٤‎ - ٥‎ - ٦‎ - ٧‎ - ٨‎ - ٩‎)

jawher | 14 years ago | on: "..best direction for evolving Java is to encourage a more functional style"

To the best of my understanding, lambdas-as-objects would mean providing structural types, i.e. generic function types that are able to describe the structure of a lambda (arguments and result type). e.g. (a fictive syntax):

    Function0<Int> f = () => 5
f here is a lambda that take no args and returns an Int. It's type is Function0 (0 for no args) and parameterized with the return type.

Another example with 2 args:

    Function2<String, Float, Int> f = (String name, Float rate) => 5
The Function* types are the generic structural types able to describe lambdas. C# has them, and so does Scala.

Java however decided not to have them, because they don't adhere well with Java's history with nominative types (a type has a name that carries sense). They rather came up with the SAM auto conversion, which is a neat idea in itself, but a bit less flexible than structural types, and may (and will lead to a Cambrian explosion in the number of types, e.g. Reducer, Mapper, Folder, Filter, Predicate, etc.)

What's even worse though is erasure: Java generics are erased at compile time, and this fucks up things really bad with overloading, so in a code like this (in the type List for example):

    public <S> List<T> stupidOpName(Function1<T, S> f) { ... }

    public List<T> stupidOpName(Function1<T, Boolean> f) { ... }
After erasure, we'll end up with :

    public List stupidOpName(Function1 f) { ... }

    public List stupidOpName(Function1 f) { ... }
i.e. 2 methods with the same name and same signature. This is bad. You don't ever want that to happen. And fortunately the java compiler won't let it happen.

So, the alternative is I said SAM (Single Abstract Method) types: no structural types, but lambdas can be automatically converted to a SAM if compatible, so you could do this for example:

    Runnable r = () => { ... }
The lambda gets converted to the Runnable type.

jawher | 14 years ago | on: I Like PHP

On why you might not want to mix your markup with the templating logic (copied from a blog post I wrote a while back [1]):

- Designers and developers will have a hard time working on the same file, especially the designers who don’t necessarily understand the templating rules language, and can easily break the whole thing when trying to modify the file.

- Also, when provided with a new version of the template text (say, a new version of the HTML from the designers), it’ll be hard to incorporate the modifications into the original template with all the template rules scattered inside it.

Regarding how to generate dynamic markup and not mixing the markup with templating logic, I'll cite approaches like Apache Wicket [2] (although you still need to add a couple of attributes to the markup) and server-side jQuery like select and transform templating, such as what is done in Enlive [3] and Moulder [4] (a pet project of mine)

[1] http://jawher.net/2011/01/06/on-templating-and-a-shameless-p...

[2] http://wicket.apache.org/learn/examples/helloworld.html

[3] https://github.com/cgrand/enlive/wiki

[4] http://jawher.net/2011/03/03/moulder-in-action/

page 1