15 ms·
Verb-Noun vs. Noun-Verb
- jkcxn 7y agoThere's no reason you couldn't type `noun.` and get autocomplete to `verb(noun)`
- nlawalker 7y agoOr just support calling "verb(noun)" as "noun.verb()" all the way through: https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax
- unholiness 7y agoAt Onshape we're considering doing this for our language FeatureScript[0], as discussed here[1] This would make the call e.g. v1->cross(v2) syntactic sugar for the call cross(v1, v2). The main reason it's not just an obvious win for autocomplete and readability is that it provides for multiple ways to do one thing, and is one more thing you need to know when learning this new language. Rather than having some code call plane->yAxis() and other code call yAxis(plane), it might be nicer to have only one way. The other counterargument: the OOP-like syntax could support the expectation that polymorphism works like e.g. Java, where e.g. v1.cross(v2) would only considers the type of v1 when deciding which overload to call. FeatureScript has multiple dispatch and will consider the types of all arguments when choosing an overload. All that said, the change it seems like a win overall, but we're waiting for the language to mature more to see if clearer arguments emerge. [0] https://cad.onshape.com/FsDoc/ https://cad.onshape.com/FsDoc/ [1] https://forum.onshape.com/discussion/comment/33495/#Comment_33495 https://forum.onshape.com/discussion/comment/33495/#Comment_...
- nlawalker 7y ago> Rather than having some code call plane->yAxis() and other code call yAxis(plane), it might be nicer to have only one way. One option is a linter/formatter that can warn and configurably push you in one way or the other.
- ljp_206 7y agoThis 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).
- munificent 7y agoI've been working on a roguelike on and off for (checks watch) about twenty years now. When I started I was an avid Angband player. I had just gotten my first laptop computer and was frustrated by how difficult it was to play using the limited keyboard without a full numeric keypad. The main problem is that the default Angband keyset uses up almost all of the letters for all of the different verbs: quaff, read, cast, pray, wave, aim, throw, etc. (There is an alternate keyset based on Vi, but I could never internalize the "arrow keys".) It was especially frustrating because, like Amit notes here, most verbs only apply to a few items. You can't read a potion or quaff a scroll, so allocating two separate keys to those actions is redundant. So in a fit of pique, I decided I would make my own roguelike with a single "use" command that could use all kinds of items. I did learn something interesting about usability in the process. One nice feature of Angband's keyset is that it's harder to accidentally use the wrong item. If you intend to quaff a potion but accidentally pick an inventory slot containing a scroll, nothing happens. The specific verb commands act like a sort of redundancy check for the operation. But, overall, I think having a single use command is better. This is orthogonal to whether the verb or noun comes first. I've just reduces the number of verbs by collapsing many of them into a single multi-purpose "use". I've gone through several iterations of the UI for the game and I'm still on the fence as to whether it makes more sense to select the item or the operation first. It's a little tricky in a roguelike because you usually need to select the item from something: either your inventory, equipment, or on the ground. So if you want to drink a potion from your backpack, it could be any of: - Use -> inventory -> potion - Inventory -> use -> potion - Inventory -> potion -> use The first option is good most of the time because the player does know what action they want to perform. But the other two are good because they give the UI a chance to show the player the inventory before they make a selection. The first option feels like a stab in the dark where if you don't know what's in your inventory, you don't know if you have anything to use in the first place. Of course, if the UI always passively shows the inventory, that problem goes away. So the visual design affects the order that operations might make the most sense. It's a hard problem.
- mrkeen 7y agoI 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).
- UserIsUnused 7y agoAlso, the autocomplete argument isn't a big argument, as writing is the less time consuming task in the process.
- stkdump 7y agoAutocomplete is one thing. Getting a list of suggestions is more important, because you might not know the name of the function.
- UserIsUnused 7y agoI agree, I guess that noum.verb() is indeed better to find those
- wvenable 7y agoKnowing what you can and can't do with an object is the time consuming part. Once you know that answer, the writing is relatively insignificant.
- coldtea 7y agoThat's not a big argument, as a process doesn't have to be "the most" time consuming part of programming to have a big negative impact. Annoying context switches and slowdowns to lookup function naming and possible options (without autocomplete) can still interfere with the flow of a programmer as he writes a program...
- scarejunba 7y agoTo test that this argument doesn't work, consider introducing a 400 ms delay on your keystrokes. Writing will still be the least time consuming task. Then compare with code you write without the delay. I have a reasonable hypothesis how the test will turn out.
- lotyrin 7y agoI 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).
- nlawalker 7y agoThis 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.
- beart 7y agoYes it is really cumbersome to use. Set-<tab> is pretty useless since you have to tab through dozens of entries if you don't know the noun you are looking for.
- jodrellblank 7y agoI don’t know that Verb-Noun is great design but I’m not convinced Noun-Verb would be any better; take your example and get rid of Set- and simply press <tab> right from the start - you have exactly the same problem of dozens of entries if you don’t know the noun you are looking for, changing the order hasn’t improved that, has it? (In reality it’s slightly less clear because tab would then have to show you other file names, executables, batch files, etc. names, at least Set- narrows it down to cmdlets to do with setting).
- oldmanhorton 7y agoBut as other comments have pointed out, Get-Command let's you search by module, noun, or verb. It's certainly not the most intuitive if you're used to normal linear autocomplete, but once you get used to it I find it works well.
- GordonS 7y agoI've never been able to quite put my finger on why I loath Powershell so much, but yes, I think this is part of it. I also dislike how verbose commands are (and the shortened versions are not safe to use cross-platform), and the weird Pascal-Kebab-Casing-Hybrid of idiomatic Powershell also irks me. Still, there is something else... I just don't like it.
- posterboy 7y agoI 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.
- bcyn 7y agoThe article is more about user experience than English language nuances. Take one of your examples, you're much more likely to know you can "board" once you know there's a "ship." Without the ship as context first, only people who are already familiar with ships know that boarding is even an option. This provides a poor experience in terms of discoverability.
- shadowgovt 7y agoThe article clarifies the difference is interesting in thinking about how these orderings simplify autocorrection. It's less about spoken language (I'm unaware of any research on whether there's anything analogous to IDE autocomplete in human cognition, or even what form that would take) and more about how the order in which data is presented to an interactive editor changes how useful the assumptions the editor makes about context can be.
- anoncake 7y ago> We "lockpick" more often than we "save face" perhaps English is a head-first language. The head of a sentence is its verb, so no.
- Symmetry 7y agoRelatedly, there's a vim-like editor that is all about moving from verb-noun to noun-verb. https://github.com/mawww/kakoune https://github.com/mawww/kakoune
- codesections 7y agoThis was mentioned in the posted link
- breck 7y agoThis 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.
- mypalmike 7y agoBoth nouns and verbs are semantically one dimensional - they are each lists of words.
- breck 7y agoIn a computer yes. But I don’t think that’s how the mind stores things.
- dmit 7y agoInteresting analogy. Only after reading this comment did I realize that my mental model has been somewhat similar. Although if I had to write it down, I'd phrase it in terms of data structures. If you have a sparse matrix of nouns and verbs where cells show whether a given verb(noun) pairing is valid, indexing by noun is clearly more efficient, because most of the time you know exactly what you're operating on, but not necessarily what the operation you want is named. The variables are likely right there before your eyes, a couple lines above the cursor, but the functions are spread out all over the code base.
- jodrellblank 7y agoHowever, 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. How does the reader trying to guess the date narrow the choice of verbs? You might be on TGGBridge jogging, and the date is irrelevant. It seems like fixing the location to TGGBridge narrows the possible verbs, but it’s still a huge list - “we were on” means you could be doing anything people can do - photographing, touring, jogging, sketching, working as a bridge repair crew or structural engineer or a vehicle breakdown van or an Uber driver or protesting or meeting up in a well known location. In English, “I was driving..” implies a vehicle, but “a car..” doesn’t imply you were driving it, or necessarily doing anything to/with it at all.
- teddyh 7y agoSee also Steve Yegge’s Execution in the Kingdom of Nouns (2006): https://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html https://steve-yegge.blogspot.com/2006/03/execution-in-kingdo...
- ergothus 7y agoThe part of the article talking about dropping to one verb ("use") made me think of the same thing ("execute"). The benefit to verb/noun (or noun.verb) is getting BOTH. If you effectively drop the verb, you lose out on half the communication. To use another comment, you may not want to quaff a ladder, but it is a bad idea to assume you just "ladder", and if assume too narrow a field it leads to frustrations. (In programming or in games. Back when I looked into text adventure games (interactive fiction) there was a truism that "use" was a _bad_ verb) If you ARE wide enough....then you have little difference between noun verb and verb noun except for the effort required. Honestly, I was more interested in the first part of the article, that talked about checking the state if the world rather than a sequence if steps.
- gnuvince 7y agoIs this really verb-noun/noun-verb or verb-object/object-verb?
- shadowgovt 7y agoverb-object / object-verb is more specific in the context of this story, yes. And indeed, when you introduce indirect objects or other fanciness, additional dimensions of complexity can be introduced (GUIs, for instance, can have ambiguity in terms of whether object-verb-indirect_object is represente by click-command-click or modclick-modclick-command).
- csande17 7y agoI 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-programming-method-call-syntax https://nim-lang.org/docs/tut2.html#object-oriented-programm...
- kbenson 7y 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.
- kerkeslager 7y agoI think vim makes more sense if you think of it like a Forth. In a general sense, the entire language is noun*verb (zero or more nouns followed by a verb). I know what you're going to say, "dw is a verb noun!" but really, it's not. w is verb--it's a function that, in this case, takes the d function and applies it to a word. The fact that it is a verb is proven by the fact that the expression executes when you type the verb. It's unfortunate that the vim verb "w" corresponds to the English noun "word", but that's probably the best that could be done given there are only so many keys on the keyboard.
- leibnitz27 7y agoHang 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.
- jedberg 7y agoYeah that part stuck out to me too. Lucky guy!
- thomascgalvin 7y ago> 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.
- saagarjha 7y agoI also think that the object-oriented syntax matches my thinking process more closely: for example, I have an array of strings, and I want to convert them to numbers, pick only the odd ones then sum them rather than "I want to sum some things…things which I'm filtering by parity…which are actually strings I'm converting to integers".
- scarejunba 7y agoThat's how the thread-last/first macros help in Clojure. You sort of specify a pipeline: ``` (-> list parseInt isOdd sum) ``` Is the same as ``` (sum(isOdd(parseInt(list))) ``` Particularly useful if you're pulling a deeply nested key out.
- karmakaze 7y agoActually FP is more often verb-verb as in compose these verby thing together in this way to make a new verb then finally give it a starting noun.
- 7y ago
- c3534l 7y agoI 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.
- TeMPOraL 7y agoKadir beneath Mo Moteh. Speaking of which, I wonder whether we'll program in Tamarian one day. Whether we'll be able to build functioning software from a really high-level abstractions, and perhaps not try to micromanage it too much. (And then when something goes wrong, the program will simply say, "Shaka, when the walls fell.")
- Izkata 7y agoYou maybe be interested in the Petrovich language: http://www.dangermouse.net/esoteric/petrovich.html http://www.dangermouse.net/esoteric/petrovich.html
- deleted 7y ago[deleted]
- mbo 7y agoNote 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).
- taormina 7y agoI find this whole conversation interesting as someone who is working on a text adventure (shameless plug: https://danger.world https://danger.world). I personally chose verb-noun, but it would be very simple to flip it around.
- excessive 7y agoOne 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.
- gambler 7y agoThis whole comment section tells me that almost no one on HN really understands OOP. OOP is not about nouns. It's about establishing protocols between subsystems. What you're describing are the typical fake "dilemmas" of someone coming from a static, class-oriented programming languages like Java. Look up Class Responsibility Collaborator exercise.
- ken 7y agoThe 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.
- BariumBlue 7y agoI 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