Programming Idioms
programming-idioms.org
programming-idioms.org
In programming, an idiom is a common, accepted way of accomplishing a task which you wouldn't figure out to do all on your own and whose meaning isn't obvious to programmers of other languages.
I suppose you could argue that certain idioms are more or less universal: using "i" as the index in a loop isn't obvious even if you know a lot of math (why not use j?).
But no one who doesn't program Python is going to figure out the first thing you do in any new Python project is write the line:
if __name__ == "__main__":
main()
The fact that it's impenetrable if it's not first explained to you that you should do that is what makes it idiomatic.Idiomatic also means particular to a specific person or group. If your website is based on comparing the same idiom in multiple languages, that's a good indication it's not actually idiomatic. That's probably just a common task.
> a style or form of artistic expression that is characteristic of an individual, a period or movement, or a medium or instrument
So it doesn't have to be inscrutable; just something that's characteristic of a particular way of doing things. The Python community favors list comprehensions over maps and filters, so using list comprehensions is part of writing idiomatic Python even though they are not in themselves impossible to understand.
The spirit is essentially pattern-like, that the specific syntax has a higher meaning in that language such that as soon as you see its shape you know what's up. Moreover, if you don't see that shape it doesn't register as "native" for that language.
In your explanation, the spirit is "entry point is main." It's true the mechanics are unusual to Python, but that's not necessary and not all that counts. If I did the name/main comparison some other way it wouldn't be idiomatic because that very specific construct is the idiom.
Some examples in other languages that aren't that hard to read mechanically:
param = param || default; // idiomatic for ES5 default
let bool = !!(whatever) // idiomatic for boolean coercion in JS
reversed_list = forward_list[::-1] # idiomatic for sequence reversal in Python
x = x >> 1 // idiomatic for x/2 in C
In some of those cases there are practical realities that also drive them (the bitshift divide in particular comes from embedded and other speed concerns) but they aren't constructs that you see elsewhere very much outside that language even if they're valid. That's what makes them idiomatic to that language.Please don't do this unless you are using a really bad toolchain: most compilers will optimize x /= 2 for you.
"The left shift and right shift operators should not be used for negative numbers. The result of is undefined behaviour if any of the operands is a negative number."
Might be one reason?
In general, always use -O2. -Os is only a good idea if you're on embedded and a -Os program fits in memory and -O2 doesn't. There really aren't any other cases where -Os is better.
I'm curious whether any compilers have specific rules to "re-optimize" obsolete practice. Like, assuming a platform does have a cheaper way to do /=2, do any compilers recognize that a >>1 in a given context is meant to be a div 2 and replace the code?
let bool = !!(whatever)
Yuck let bool = Boolean(whatever)while (dest++ = src++)
I'm sure I've botched it (but I will not google that)
I believe the confusion probably stems from the word "idiomatic," which means "using, containing, or denoting expressions that are natural to a native speaker."
i.e. "idiomatic English" simply means that it sounds like a native speaker. Likewise, "idiomatic python" would be code that reads like a fluent python programmer.
1. idiom: a group of words established by usage as having a meaning not deducible from those of the individual words (e.g., rain cats and dogs, see the light ).
2. idiomatic: using, containing, or denoting expressions that are natural to a native speaker.
Also "connected" is "idiosyncratic," and that means yet a third thing. "Idiosyncratic programming" would be the opposite of what you want!
(Definitions from Oxford University Press / https://www.lexico.com/en)
> A form of expression natural to a language, person, or group of people.
> The dialect of a people or part of a country.
I'm sure there could be grammatical nitpicks, but the word choice is appropriate.
(Back when more people were involved in agriculture, they knew that a “bucket” was a type of frame used in slaughtering livestock.)
The first cookbook I recall was for Perl, and I later saw other language users try to emulate that, and even use the tasks it identified as a template for their own language's cookbook.
I save "idiomatic" for programming linguistic style guidelines that, for many tasks, help select among multiple ways of doing a task (or of larger structuring/approach). For example, in Scheme, tending to avoid mutations, structuring algorithm implementations to use tail calls, using first-class closures, using syntax extension for minilanguages/DSLs, etc. Pythonistas might call their own popular style "Pythonic".
There's overlap with cookbook-type stuff. For example, in some language that permits both approaches, maybe the approach of folding over a set of filenames is arguably more idiomatic than the approach of constructing a list of filenames. Consequently, the cookbook example might be of the folding approach. I don't want to call that particular task an idiom, because I find the term useful for a different purpose, but there's overlap.
Cookbooks often answer the question "which library and/or calls do I use".
If the cookbook spends time on more general tasks, like "coding an algorithm" or "traversing a collection", then the discussion might be more about what's idiomatic in the language.
Some of the fuzzy distinction might be analogous to the fuzzy distinction between language and library.
Maybe someone has better terms or definitions?
Noah: "Do you even know what an idiom is?" Archer: "colloquial metaphor"
The phrase “colloquial metaphor” itself feels idiomatic from a context you’ve never considered, but appears to be obviously correct.
Just that little snippet of Python there could be used to quickly and effectively introduce an experienced non-Python programmer to three or four important ideas in Python.
"One common solution is to use a static field to store a single instance of Random and reuse it. That’s okay in Java (where Random is thread-safe) but it’s not so good in .NET – if you use the same instance repeatedly from .NET, you can corrupt the internal data structures." [2]
Very often the very same resources which claim to be the source of truth provide bad code examples.
[1] https://www.programming-idioms.org/cheatsheet/Csharp
[2] https://codeblog.jonskeet.uk/2009/11/04/revisiting-randomnes...
Case in point, Idiom #46 in C[0] uses strncpy and predictably fails to correctly terminate the buffer.
Idiom #55[1] converts a integer to a string with itoa, never bothering to mention that it isn't part of the C standard or POSIX, while for some reason using a 4096 byte big output buffer.
Idiom #39[2] first example uses clrscr(), which I assume is some sort of old DOS function? The entire example looks unrelated to the problem.
The idea is certainly good, but you need some serious vetting system to make this usable.
[0] https://www.programming-idioms.org/idiom/46/impl/477
That’s the fate of all such sites. They start with a nice idea and a good intent, but the crowd fills it with crap, nobody cares/is able to screen it, and it instantly becomes an unreliable source of nonsense.
Ed: btw, #1 is terminated by calloc(6), but it is indeed a trip mine looking for prey. It is unknown if strncpy was used intentionally or out of ignorance and if the next person will be aware.
Yet this seems to be the perfect place and time to remind the kind audience that sizeof measures the number of char-sized chunks, thus sizeof(char) is always the constant 1, no need to spell it out.
calloc returns zeroed memory.
For example:
"""
Remove all occurrences of string w from string s1, and store the result in s2.
var s2 = s1.replace(w, '');
"""
Since w is a string, this will only replace the first occurrence, not all occurrences.
var regex = RegExp(w, 'g');
var s2 = s1.replace(regex, ''); str.split(before).join(after)You could try to escape those special characters but that is potentially error prone.
For an arbitrary w, one approach is something kind of awful like:
let s2 = s1;
while (s2.includes(w)) {
s2 = s2.replace(w, '')
}
Edit: minitech's solution is better.It doesn't provide any indication of whether an entry has been vetted. At least with stackoverflow you can see discussion in the comments and guess whether an answer has been critiqued.
If you have sufficient expertise in an area and poke around SO long enough, you'll spot the problem with an egalitarian system soon enough: the blind leading the blind.
That's what I was thinking. There are no threads in the example.
Thread safety is something that needs to be touched on constantly, and it's smart to write your code such that it would be thread safe. Because otherwise, it just looks like a normal function call. And it could take someone ages to figure out why everything is breaking if they were to actually use that example.
If "idioms" mean code that adheres to best practices, given that C# code is frequently threaded, their examples should mitigate common threading issues.
It will be ignored. StackOverflow guys and all participants have put an enormous effort into making it at least partially trusted source of snippets, and I hope it will never be outranked by sites like this.
(to creator: sorry for this, but in a long run it only harms everyone, unless you “die” for it)
Programming Idioms has a slightly more modern interface, but what matters more is the content. Rosetta Code has more content and better content. If you don't like Rosetta Code's interface, I'd rather you tried to improve Rosetta Code rather than splintering the already-small community of people producing this sort of content.
That's debatable. I suppose it's better than nothing for complete noobs, but a lot of the examples on that site are even worse than the crap found on Stack Overflow.
Take this for example: http://rosettacode.org/wiki/FizzBuzz#ES6
Way to overcomplicate FizzBuzz!
I do agree it needs improvement. It would be nice if it had an interface to browse and do a:b comparisons in a more fluid manner. The programming idioms site does this well.
I'm a bit reluctant to trust the quality of this, however.
The first example I looked up was "Format date YYYY-MM-DD" in Python, which wanted me to use "isoformat()", which produces something else.
It was easy to correct, but I'd like to see a more "democratic" approach to getting correct examples, not just taking the latest one as fact.
edit: Sorry, more precise critique of the usage of "isoformat" would be "which _might_ produce something else" (it depends on the resolution of info in the date object).
In regard to the second, isoformat on a "datetime" will give increased resolution beyond "YYYY-MM-DD", but a "date" object only resolves year, month and day and such a call will indeed yield the correct output (per the linked documentation at [2]).
[1] https://www.programming-idioms.org/idiom/99/format-date-yyyy...
[2] https://docs.python.org/3/library/datetime.html#datetime.dat...
> I'd like to see a more "democratic" approach to getting correct examples
Me too! Stackoverflow contributions are cc-licensed so maybe a tool to easily curate answers to classic issues and build on top of them would work well. I'm not sure crowdsourcing programming idioms from scratch would be the easiest way to go as I feel the work is mostly halfway done out there (but sure could use some curation).
Actually now that I think about it, that's related to what stackoverflow tried to do with their documentation by examples attempt (cf. https://meta.stackoverflow.com/questions/354217/sunsetting-d...).
I am not sure what you mean by "the resolution of info in the date object". Can you clarify?
import sys
sys.exit(0)
Well, I guess I've been reinventing the wheel for my whole career... and thank god I did, my wheel is not only more performant, but also shorter and produces cleaner code (in my subjective opinion). As simple as: # nothing if foo:
exit(0)
more_code() raise SystemExit(code)
is nicer (and does not require an an import).From Python docs: https://docs.python.org/3/library/exceptions.html#SystemExit
> exception SystemExit
> This exception is raised by the sys.exit() function. It inherits from BaseException instead of Exception so that it is not accidentally caught by code that catches Exception. This allows the exception to properly propagate up and cause the interpreter to exit. When it is not handled, the Python interpreter exits; no stack traceback is printed. The constructor accepts the same optional argument passed to sys.exit(). If the value is an integer, it specifies the system exit status (passed to C’s exit() function); if it is None, the exit status is zero; if it has another type (such as a string), the object’s value is printed and the exit status is one. > A call to sys.exit() is translated into an exception so that clean-up handlers (finally clauses of try statements) can be executed, and so that a debugger can execute a script without running the risk of losing control. The os._exit() function can be used if it is absolutely positively necessary to exit immediately (for example, in the child process after a call to os.fork()).
Replying to your comment regarding:
> Isn't raise for "throwing" exceptions/errors though?
Well, some would argue that is idiomatic in python. A quick google search not only autocompletes "exceptions for control flow" to "exceptions for control flow python", but on the second search, most results discuss that (with many agreeing). I guess you can say most python developer wouldn't immediately assume it's an error. I definitely can say, I don't.
For cli tools, on the other hand, there are definitely legitimate cases for exiting early.
def main()
blablabla
if foo:
return bar
...
return 8
if __name__ == “__main__”:
os.exit(main())
Of course that’s just my advice / opinion / preference, other ways are valid as well...These are not the same semantically. It may or may not be practical for you to prove that your program is still correct if finalizers are skipped.
In 99.9% of cases it holds true, it's easier/ cheaper to use existing/ off-the-shelf solutions.
The other 0.1% (not absolute numbers), it makes sense to innovate.
Quite a few idioms fall into this category, like premature optimisation being the route of all evil. You really don't want to be on either end of the scale.
I don't think the website is redundant. Something I think is useful to be able to compare languages, especially when using a new language. Plus, languages are interesting, they're not just a syntax, they often bring a different way of thinking.
One issue with the website is that there is no indication of example quality. For instance, the B-Tree* in C# has some issues[0]. Using classes instead of structs is horrible for memory management and garbage collection. As does not constrain the generic type to structs ("where T : struct"), this continues on from the above. None of this would be apparent unless you understand .Net's memory management, inheritance, garbage collection, and spent some time with generics. Many of the other languages have got this right.
[0]https://www.programming-idioms.org/idiom/9/create-a-binary-t... *I have often wondered why trees aren't standard collections, inserting nodes and tree rotations etc are common use cases for B-Trees. This does feel like re-inventing the wheel, giving developers plenty of opportunity to screw things up. Tries are another structure I think they have left out, there are times when tries are often a better solution than dictionaries (urls spring to mind).
Now they wish they had taken the time to just write their ten lines wheel themselves...
It's almost as if there's a balance...
But sure, reinvention has to happen sometimes. Doesn't mean you are the one to do it. It's like the rule against implementing cryptography.
I know what I need. I don't know what it's called in English. It's faster to re-implement it than to learn the vocabulary.
f <$> x <*> y <*> z
to "map a function over three values"1) The problem description specifies "Each character must be handled correctly regardless its number of bytes in memory.", for which the C implementation rather plainly fails.
2) UTF-8 is so ubiquitous nowadays that any string-manipulating function that fails to correctly handle multibyte UTF-8 characters ought to be considered broken.
def adding_will_overflow(x, y): return False
I have no idea if it's actually true but I find that funny.
Unless you're using a C bind, like numpy.
"Idiom" means something that is done in a characteristic style. For example, in Python, it's idiomatic to use list comprehensions rather than for loops.
I don't see how getting the size of an array could be idiomatic in that sense, because there is always only a single way to do it, it's never a stylistic choice.
For example, R is a statistical programming language where almost all data structures and operations are for vectors or arrays. But it's not unusual to see people on StackOverflow or blogs reinventing wheels like map/reduce/filter with for loops. I agree it's just inexperience that led to it, but the "intended" way is still idiomatic.
You list VB - but you don't say if this is VB.NET, or prior VB versions (3,4,5,6)? VB.NET isn't quite identical to the others...
...and VB is nothing like plain-old BASIC (and later dialects). In fact, you might lump them all under BASIC, as VB owes more to BASIC than being it's own thing (though VB.NET seems more a name than being BASIC - just my opinion, though, as a long time ago VB3-6 coder - I'd call it "BASIC-ish").
Other than that - this looks interesting. UI could use a bit more work, but seems like a good start.
Added a request for Racket support!
The problem with applying this to programming is the implication that there are languages, frameworks, patterns, and idioms which are equivalent to the wheel, in that there always exists one objectively correct, perfect solution which can't be improved upon. I don't believe programming has the equivalent of a wheel, yet.
What people tend to mean when they say "don't reinvent the wheel" in the context of programming is either "don't waste time writing code that already exists and is adequate" or "don't use $X because I like $Y."
Is the right way to delete a file
result = os.deletefile(path)
or is it try { os.deletefile(path) } catch (ex) { log(ex) }
and what is the difference? Both may be valid and idiomatic in the same language. With more context such as a forum dialog or a StackOverflow question, these things are usually ironed out. But trying to do the same thing in Haskell (where you might have monadic error handling) or java (where you might have some exception handling chain) is very different even though the same function call is used in the end to actually delete a file.The checklist also seems to favor dynamic languages. E.g. does Go deserve to miss a checkmark because you can’t determine if a variable exists at runtime (only at compile time)? I can sorta see the source inclusion checkbox, but it’s not entirely clear from the example if this is testing for a macro support, AOP, or dynamic loading of libraries.
About the site design, the little menu on the left should better not move the content window to the right. Now, when you scroll down in 'all idioms' for example, the list is right aligned and left has useless whitespace. A horizontal menu or dropdown would be better I guess.
https://www.programming-idioms.org/idiom/99/format-date-yyyy...
The first listing was using a `SimpleDateFormat`, which for a long time really was the best way to do this. But now I would never recommend that over `String.format`, especially with the potential threading problems in the former. But the latter was not available until Java 1.5.
Downvotes are typically reserved for wrong, not merely suboptimal. Especially since optimal and thereby suboptimal can change based on circumstance.
On Fetch: https://gomakethings.com/why-i-still-use-xhr-instead-of-the-...
const _fetch = window.fetch
/** Fetch overload that handles error status */
export function fetch(input: RequestInfo, init?: RequestInit) {
return _fetch(input, init).then(checkResponseCode)
}
function checkResponseCode(response: Response) {
if (response.status >= 400) {
const err = new Error(`Error ${response.status} from ${response.url}`) as any
err.fetchHttpResponse = response
throw err
}
return response
}
/** Convenience method */
export function getJson<TJsonBody = any>(
input: RequestInfo,
init?: RequestInitJson,
) {
return fetch(input, init).then((response) => response.json()) as Promise<TJsonBody>
}Sorry, [nim] is currently not a supported language.
What's better about this one?
My real question would be, what does this do that Google's Stack Overflow hits don't do. One would hope that the answer is, "Give me advice on how to do it in Python 3.6 that didn't get downvoted to death because there's already a SO question on how to do it in Python 2.7." But the cynic in me knows that, in software, particularly software's social environment, the only effective way to clear out the old, obsolete, broken wheels so they're not always in the way is by re-inventing them.
I think that you're painting with a little too broad a brush, the inverse is true too, I've seen way too much blind application of GoF patterns by professional engineers.
I think the key word is understanding. what each idiom needs is a good rubric explaining why this is the/a correct approach, but that is much harder to provide
For myself I'm a 25 year industry veteran, with 35 years of self-taught programming experience.
My experience with stereotypes and generalizations is that the problem is not so much that they might be wrong, but rather that they are always incomplete