Why stop at print statements? After all if you find yourself successfully using the print statement from some other language, you might accidentally also use its if, for loop, file handling and class declaration constructs among many others. Who's looking out for those people? This is just the beginning!
I'm a primarily Python dev, have been for a long time. Lately I've been working in Javascript/typescript and there is no worse antifeature than having 3 different ways of doing the same thing.
You try to figure out how to do something, you see 3 different solutions and you ask yourself, what's the difference? What's more correct? Will I need one over the other? Are they compatible? Is one way better supported than the other?
The amount of time I've spent looking up differences between two APIs or two paradigms in Typescript is seriously ridiculous. And it feels really bad to not recognize something you've done before because it's written differently.
Common culprits: require() and imports, the countless ways of creating classes, the crazy amount of different ways to implement similar or identical workflows in webpack and pretty much the entire JS ecosystem in general.
>You try to figure out how to do something, you see 3 different solutions and you ask yourself, what's the difference? What's more correct?
Maybe I'm just bad programmer, but I whole heartedly embrace languages that let me express myself in a way I want to. Big part of my day is dealing/writing/converting stuff to Python and part of me wishes there wasn't "the Zen way" to do things, but instead I could express myself, but this kind a goes beyond Python in a sense that it doesn't have the syntax I would like to use.
I'm by no means saying that JavaScript is any better. So far my personal favorite language has been Ruby (and not the Rails way), for some reasons it feel like with Ruby I can just tell the code what to do instead of having to explicitly command it to do what I want step by step.
> You try to figure out how to do something, you see 3 different solutions and you ask yourself, what's the difference? What's more correct? Will I need one over the other? Are they compatible? Is one way better supported than the other?
I've always wondered this: would it be that bad, if you could easily guarantee that all those formats really are equivalent? (maybe by being able to check a unique identifier of the function to which the expression is going to be compiled).
In the case of this library, the semantics are simple and clear: I have a string object, and I want its contents to be poured on a predefined output device; maybe converting on-the-fly some escape characters in the string to the values of some parameters.
Provided that you don't deviate from this specified meaning, is it that bad that the language accepts any common syntax?
I understand the "being harder to recognize what it is doing", but I think that might be somewhat alleviated by the feature I said above of unambiguously resolving to a single entity in the programming language.
As a primary js developer (about 10 years) who in the most recent two years has done more and more es6 work I will revel in the day I don't have to use it in my day to day. I toy with clojure in my free time and even python and just hate the way the JavaScript language has been taken over not just by trends but with what I think are poorly thought out syntax additions. JavaScript seems like a language that has no opinion on the best way to do a thing, no well thought out constructs to eliminate boilerplate, and just sits there and waits for a Bower, and mom, a lodash, or a Babel to come along and tell it hoe to be a proper language.
I also think we should write our programs as concise and simple as we can. There should really be one obvious way to do it.
I recently read the statement that "If you can solve parsing Perl, you solve the Halting Problem "(http://www.perlmonks.org/?node_id=663393). This is not a joke, it's serious.
Python and Go keep their promise to stay simple. However I believe, metaclasses, asynchronous programming and constructs like "yield from" and the whole itertools library could be better engineered. And lastly with new approved PEPs like concerning string interpolation etc., I believe Python is making compromises in its core ideology. In contrast, in go if you want to allocate something you just use make(), if you want your code to run concurrently you just use "go", if you want to send messages between threads, you just use channels. The complexity is well hidden in the language itself.
What I don't like in Java for example is that, as a general purpose language, in each version new features are added. And these new features add complexity, and complexity leads to mistakes.
Perl I understand, it was designed as the first postmodern programming language. Javascript was written in a very short time and intended to be a browser scripting language. But Typescript?, with Typescript there is no excuse. I guess, this is Microsoft's policy: Worse is better, make everyone (or at least revenue sources) happy. You want feature x, they add it, you want lambdas, they add it etc.
Maybe I'm a bit tired of hassling through chaos, but I want my codebase to be structured. If I don't like an API, I take my time and write a simpler abstraction.
One programming advice stuck in my mind from the Art of Linux Programming: you should focus on data structures (a.k.a structuring).
I think this advice is true for all aspects of life. You need to set aside a place for your things, if you want to live/work in a tidy environment. You need to plan your day, if you don't want to fall apart. You need folders to organize your e-mail/documents. You need to structure your programs in meaningful abstractions into seperate modules/subroutines.
To be fair on typescript, I think it's inheriting most of these issues from wanting to give a better way to do things, but keeping (near-)full backwards compatibility with JS.
I feel you on the JS/TS front, but to be honest it's somehow less of an issue in Nim. Not sure why, but everyone does really follow some pretty simple conventions.
This is one of the reasons I love Lua. I'm constantly pleasantly surprised by Lua. It defines a few simple primitives, and allows you to do whatever you want with them, even to the absurd.
> for a language proud of getting rid of parenthesis
Er… what?
Python doesn't have braces, it has plenty of parenthesis. In fact, Python 3 added more since it upgraded several keywords to functions (not just print but also exec, and some forms of re-raising)
> Little known fact: The addition of `exec`-with-parenthesis actually long predates Python 3. Python 3 just removed the old, braceless version.
That's not really true, although the syntactic compatibility does make for conveniently trivial cross-compatible code, Python 3 did not "remove the old, braceless version" it converted exec from a keyword (which could accept a single tuple parameter) to a builtin function (which takes up to 3 parameters). Which had the side-effect of requiring parenthesis.
Incidentally, the print-tuple-trick is cute, I hadn't considered it.
Print chevron is super awful, it's unreadable, hard to remember and difficult to search for.
The print function was a welcome improvement: it's not a statement (so can be used in a lambda, no need to fall back to sys.stdout.write), it doesn't use weird-ass syntax to redirect or suppress the final newline and it's more extensible (e.g. "end" or "flush" kwargs would have been… challenging to add to the keyword version)
I'm not going to discuss perl readability, but the fact is that I cannot simply 0%% to beginning of the block in "readable" python. ?:$<CR> does its job though.
Is there a LISP with significant white space in place of parentheses? Our two groups could be united by the disgust of the rest of the programming community.
Works with both Scheme and Common Lisp, two most popular Lisps out there. Nobody uses it because paredit/parinfer is just too convenient, but the option is there.
Worth noting: the language's syntax must still be minimally compatible with Python -- this isn't some sort of magic parser hack, it's just adding functions and types with special behaviour (like having "cout" be an object that overrides __lshift__). Now, given that many Lisp and Lisp-likes support ridiculous parser hacks (Scheme/Racket come to mind), I bet you really could pull off "Anyprint" in one of those languages...
printf("printf %d\n", 10);
fmt.Println("hello")
cout << "Hello, C++!" << endl;
Print["Hello from Mathematica!"]
console.log("yes");
System.out.printf("java stuff\n");
Ada.Text_IO.Put_Line("Ada is cool")
Really funny, including the testimonials:
> Anyprint has many glowing reviews from its many satisfied users:
>
> * "omg pls"
> * "what is wrong with you"
> * "That's stupid and not useful."
> * "Please add my testimonial: "very accurate testimonials"."
> * "kragniz, please stop writing questionable python metamodules :v"
Buffering of Cs stdout is implementation defined. For Linux it is only line buffered in an interactive terminal session and fully buffered otherwise.
> Are you saying you never want to flush?
90% of the time not. The other ten percent include asking for user input, which causes an implicit flush since std::cin is linked to std::cout, and debugging an ugly heisenbug.
In all seriousness, it never occurred to me before that because of access to "globals", an import statement can introduce (or alter the value of!) unexpected names.