Verb-Noun vs. Noun-Verb

Sindisil | 282 points

> Something I noticed at the time was that the syntax for functional languages tends to be verb then noun: f(x), whereas the syntax for object oriented languages tends to be noun then verb: x.f().... There's a big difference in usability though: auto-complete.

Auto-complete also really helps with discoverability. Consider checking for the presence of a key in a map/dictionary. In Java, auto-complete will quickly lead you to `map.containskey(key)`. In Python, though, you'd have to know that the syntax is `if value in dict`.

Now, let's check for the presence of a value. Auto-complete again quickly leads you to `map.containsValue(value)`. In Python, Google tells me that it's `if value in dict.values()`, which seems more difficult to stumble upon.

And that's for a built-in data structure. A lot of my job involves trudging through other people's code, trying to figure out how they architect their ball of cats. Auto-complete is a great tool for that; it lets you quickly and easily poke around, and see what the various nouns in the system can do.

thomascgalvin | 5 years ago

I remember doing some research on language for a psychology course in college and I think it's important to warn hacker news that the expieriences people have with nouns being more intuitive and fundamental is absolutely not a cultural universal. Westerners place unusual emphasis on nouns and while it may be that "get" is less specific than "item_id" in English, it may be more be the opposite if you speak a language that has specific and concrete verbs and abstract nouns. This is one of those times where your intuition about what is logical and obvious might be wrong.

c3534l | 5 years ago

> vim's commands like d0 are verb then text selection (noun), whereas in more conventional text editors (including Emacs) you'd first select some text (the noun) and then invoke a verb like delete.

I would say vim is also noun-verb as you can select text and then tell it to perform an action on it, but supports convenience methods for verb-noun, or just verb. It's just that most the verbs also have a default selection they apply to as well, whether it be a character, a line, or some larger block of content. Thus, 'x' deletes one character, but 10x deletes 10 characters, using 'v' to select text and then x deletes the selected characters. 'dd' deletes the default (current) line, '10dd' (or 'd10d' to mix it up) deletes the next 10 lines, using 'v' to select a range of lines and then 'd' deletes those lines. Additionally, you can just define a range of lines to apply a command do in command mode: 10,20d deletes lines 10-20.

kbenson | 5 years ago

This gives words to a frustration that I've had with many roguelikes. I don't want to /drink/ -> /ladder/, I want to do ladder things with the ladder, which should be a very short list. Freedom does not great game design make (by default).

ljp_206 | 5 years ago

One of the things I dislike about the OO noun.verb() syntax is that frequently you have multiple nouns. For example in some graphics systems, you've got a canvas to draw on, a pen which knows styles for line thickness or dashes, a brush for how to fill, and a shape to be drawn. Who owns the verb? They kind of all do:

    canvas.draw(pen, brush, circle)
    circle.draw(canvas, pen, brush)
    ... and so on
The other issue I have is in closed object systems where you can't add new methods to classes in the library. Say I want to add a new type of shape, maybe an emoji face composed of several circles. Depending which class owns the methods, my new smiley method stands out from the other shapes which are provided by the library, and I think the lack of symmetry is ugly:

    canvas.draw(pen, circle)
    draw(canvas, pen, smiley)
For simple cases, inheritance solves this, but then you get into worse trouble when Alice builds a derived class to support smileys, and Bob builds a separate derived class to add stick figures. Which version of the canvas do I instantiate to support both? Maybe this implies the method should be on the shapes, but I can contrive other examples which break that too. (Another approach is monkey patching, which has it's own flaws, and so on.)

There aren't many languages which support multimethods, but overloading functions is sufficient for statically typed cases, and it's appealing (for me) to have the same syntax for "builtin" methods and ones you add yourself:

    draw(canvas, pen, brush, circle)
    draw(canvas, pen, brush, smiley)
Other people have mentioned languages with "uniform function call" syntax (where f(a) and a.f() are synonyms). I guess that's ok if you're in the "there's more than one way to do it" camp. I don't think that completely addresses the problem though. I could make more examples, but this post is getting long already.

For what it's worth, I really dislike it when languages implement operator overloading for binary operators as methods on the first object without a way to dispatch to the second object. This makes it very difficult to have your new types play well with the builtin or library provided types. Binary operators really are functions with two arguments.

xscott | 5 years ago

This seems to jive with my experience, but I'm trying to formulate a back-of-the-envelope mathematical explanation. Here's my thinking: nouns are in 3D space and verbs are in the 4th dimension (you need the concept of time to have a verb).

By going "noun-verb", you are fixing the first 3 dimensions and leaving one remaining (hence the ~1000x reduction in search space for autocomplete). By going "verb-noun" you are only fixing 1-dimension, leaving the other 3 unknown, and autocomplete would have a larger search space.

Putting it another way. If I started a story "the year was 2015", I've only narrow the one time axis, but the "noun/place" hasn't been narrowed at all, so you still have a sphere of possibilities. However, if I started a story "we were on the Golden Gate bridge", I've pinpointed the 3-dimensions of place/noun, and now the reader only has to pinpoint where on the "time-line" we are. And even that timeline has been shortened to a segment of ~100 years.

breck | 5 years ago

This is exactly the thing that has always bothered me about PowerShell. A lot of PowerShell's effectiveness derives from the number of nouns that Microsoft has built support for, and a defining trait of any given script is usually the set of nouns it operates over, so it's weird to me that all the commands start with the verb.

nlawalker | 5 years ago

I like Nim's approach to this issue: `f(x)` and `x.f()` are completely equivalent to one another.

https://nim-lang.org/docs/tut2.html#object-oriented-programm...

csande17 | 5 years ago

I clicked the link hoping it was about language. But it is about rogue likes and programming.

Since english can verb nouns like nominalization, i can't tell what the benefit is. one boards the board of a ship, levers a lever, and locks a lock.

We "lockpick" more often than we "save face" perhaps English is a head-first language.

In formal writing, a difference exists between nominal and verbal-style.

posterboy | 5 years ago

Relatedly, there's a vim-like editor that is all about moving from verb-noun to noun-verb.

https://github.com/mawww/kakoune

Symmetry | 5 years ago

I used to prefer car.drive(), now I prefer drive(car).

I don't buy the auto-completion argument. Can my IDE really tell me all the ways I can use an Integer? I don't think so.

When it hit home for me was when Java 8 lacked Stream.takeWhile(predicate) and I decided to implement it for myself. I could implement takeWhile(predicate, stream), I could not implement stream.takeWhile(predicate).

mrkeen | 5 years ago

I wonder if the ergonomics of text based adventure in SOV-order languages is/was substantially improved for this reason.

北に行く (north, go) ポーションを飲む (potion, drink) スライムを戦う (slime, fight).

lotyrin | 5 years ago

There's no reason you couldn't type `noun.` and get autocomplete to `verb(noun)`

jkcxn | 5 years ago

Hang on. Is no-one else here just blown away by the fact that the guy lucked into meeting Garriot & Watson? Man, I'd have given my right arm for that as a kid.

leibnitz27 | 5 years ago

See also Steve Yegge’s Execution in the Kingdom of Nouns (2006):

https://steve-yegge.blogspot.com/2006/03/execution-in-kingdo...

teddyh | 5 years ago

The flip side of this, that they don't mention, is that this asymmetry exists only if you design your interfaces in FP / OO languages differently. Most OO designs I've seen have a large number of classes, each with very specific methods. Most FP designs I've seen have few (or even zero) custom types, and a large number of methods can apply to a large number of types.

As Alan Perlis said back in 1982:

> "It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures."

When I'm writing in a FP language, it's true I don't get much autocomplete help, but the upside is that I've got 100 core functions that operate on almost anything. Even if you flipped around the order of the syntax on screen, autocomplete wouldn't help much, because you can apply any verb to any noun. I rarely have to convert between types, and when I do it's a couple words at most.

When I'm writing in an OO language, with typical class libraries and frameworks, I get a lot of help from autocomplete, because once you know the "type", there's only a few things you can do with it. The corollary is that I usually spend half my program converting from the type I have to the type that I need.

(Think about English. We could simplify the language by eliminating words like "eat", and just say "I'm going to go use lunch", but then we wouldn't have the word "eat" available for any other nouns, even where it'd be helpful and clear.)

> It is better for programmers if they can choose from two medium length lists than to have to choose from a very long list (where a lot has to be typed before it's useful) and then a very short list (where not much is gained).

This doesn't tell the whole story. As they say, you write code once, but read it many times. I'm perfectly OK with giving up autocomplete (for writing) if it means I don't have to spend twice as many lines of code (for writing and reading) to convert an X to a Y just so I can call f() on it.

The more generic the functions, the less code I have to write, and having less code has huge benefits across the board -- for writing, reading, debugging, testing, performance, and so on. Autocomplete can be nice, but it's not nice enough to want to sacrifice everything else.

ken | 5 years ago

Note that not everyone FP lang is verb-noun. Sure, most are, but your F#/Elixir/Scala's are more often than not written in a noun-verb form with the `|>` operator or something vaguely equivalent (syntax extensions in Scala's case).

mbo | 5 years ago

I think what the topic gets towards is that if you view all possible actions as a multi dimensional array of (all nouns)*(all verbs), it makes sense to first choose the one of (nouns, verbs) that is initially the smaller set

BariumBlue | 5 years ago

I find this whole conversation interesting as someone who is working on a text adventure (shameless plug: https://danger.world).

I personally chose verb-noun, but it would be very simple to flip it around.

taormina | 5 years ago

Is this really verb-noun/noun-verb or verb-object/object-verb?

gnuvince | 5 years ago