Lets compare it to the Python version. It looks much shorter, but many constructs are similar to what you wrote and it can be argued that the Scala code is merely a rearrangement of the tokens in the Python code.
So let us explicitly call out the tokens/items I did not use in the Scala code, but you did in the Python code.
domains = []
domains.append(domain)
out.close()
infile.close() // I think you missed closing the input file, a handle leak bug
The map method encapsulates the construction of the output list and the FileIterator and toFile methods encapsulate the opening and closing of files.
In particular, the Scala code hjas no handle leak bug.
What functional languages are really good at is abstraction. map has abstracted away iteration and construction of an output list, while the file handling methods abstract away resource usage.
As programs get bigger and more complex, this power of abstraction becomes increasingly powerful.
(Note that FileIterator and toFile are constructs that I wrote for myself a long time ago, differing constructs are available in the Scala std lib)
It should be fairly clear from the responses to your post that the characterization of this reaction as a "lynch mob" does not meet the established standard of usage of this term.
Getting universally criticized for a statement is not a qualification for assuming "lynch mob" victim status.
> I meant the forces that drive lynch mobs are driving people here.
This particular statement can be interpreted in so many different ways that it remains meaningless as it stands.
I think Armstrong might be discomfited by the well deserved online education in social etiquette and the priority of life (of poorer people) over money. He sorely needs it and he will be the better for it, though a complete cure for him seems impossible.
> Did he say that?
Did I call you an ignorant money peddler, who thinks he is very smart because he can micro analyze statements and completely ignore the context in which the statement was made, as per his convenience?
> Furthermore, insofar as you create competition to hold that position, you're creating a destructive work environment. Software development is a cooperative activity that can't be efficiently partitioned.
Seen way too many of these kinds of management structures. The management decides to appoint the crony as the lead, because picking the best developer is "wasteful" and creates a "destructive work environment". The amount of cringe inducing perversion of logic in the comment above is a tragedy because of its pervasiveness. On the flip side, these kinds of organizations are not too hard to avoid, doomed startups and successful behemoths - both fit these criteria. A smaller company with decent growth is probably the better bet.
You can pry the super powerful type system, functional programming support, monad comprehensions, library ecosystem, IDE support from my cold dead hands :D
Reading your response, I think I need to read more on the topic. I haven't read Moggi's paper and I need to look up on the continuation Monad. You are probably correct and I am probably wrong. However, I will let my original post remain as a matter of historical record :-)
I don't know how else to put it, but at least half of what you have written above is completely wrong.
> but they're less useful in other languages where you already have effects everywhere.
Scala has side effects everywhere, yet the Monad is extensively used in Scala programs. Monads have nothing to do with "effects".
Monads are not used to decide the kind of "effects" you are allowed. By calling every Monad a kind of "effect", you are just begging the question. Monads are merely objects that follow 3 monad laws, no more no less.
> This is why Haskell is pure despite having effects. Haskell programs don't do IO, they yield control to the runtime environment whenever IO needs to be done.
How is this different from a C program? Haskell is pure in the presence of IO, because the type system tracks IO calls and forces any function that even indirectly refers to a quantity obtained via IO to modify its type signature to reflect the IO action. This can be done with/without Monads. Haskell IO is a Monad, because it pretty much analogous to the State Monad and Haskell has special Monad syntax that lets you pass the World State implicitly and write imperative code in an imperative style.
Any one with work experience and common sense can tell that talking to boss^2 and HR is a recipe for disaster. You are also unwilling to challenge michael's claim that he was meeting expectations and in the midst of a transfer. You also think restricting transfers for 1.5 years is not a problem. Is there any problem within Google that you are willing to admit?
You sound like an HR drone tasked with attacking michael's record with false data. You haven't responded to his claim that his record met expectations. Unless you use a real identity, your claims will have no credibility.
Off topic comment.
Just tried the surface RT at the Microsoft store today. I think its awesome. I am considering the surface PRO for purchase. However, I am concerned that I cannot use it as a "laptop" i.e. balance the surface while typing with the keyboard on my lap. This is probably 50% of my usage scenario. If there is a heavier version of typecover that can support the tablet without a kickstand when placed on the lap I would rush out to buy the Pro version.
2. A recursive descent parser where you can declare your grammar as in yacc i.e. it is not a separate compiler generator but a regular library, and the code is type safe unlike yacc. The best part is that the actual library is just 2 lines of code, thanks to the magic of lazy evaluation and a powerful type system.
result v = \inp -> [(v,inp)]
p `bind` f = \inp -> concat [f v out | (v,out) <- p inp]
I have never agreed more with a HN comment than this time.
This has to be the worst post by Yegge in terms of the negative impact it can have on software engineers and engineering.
He took a technical topic and labelled his belief system as "liberal" and the others as conservative. When some one proposes a technical approach he doesn't like, he can simply call him a "conservative-not that there is anything wrong with that".
Yegge is an average programmer at best. He wasn't able to maintain a simple 2D game and very easily blamed Java for it. It was a clear case of PEBKAC. It is absurd and unsurprising at the same time, that the simple act of blogging can some how elevate a programmer to expert status.
Yegge clearly has no idea what he is talking about. I am currently working with Scala which is apparently Hardcore conservative. Look at his characteristics of liberal languages.
1. Eval. - scala has a REPL, so u can do an eval if you wish.
2. Metaprogramming - scala macros
3. Dynamic scoping - No
4. all-errors-are-warnings - Meaningless bullet point, all languages encounter statements that it cannot meaningfully interpret. This statement just shows you Yegge's massive PL understanding deficit.
5. Reflection and dynamic invocation. RTTI - Scala has these.
6. The C preprocessor - Nope
7. Lisp macros - scala macros.
8. Domain-specific languages (for the most part). Optional parameters. Extensible syntax. Downcasting. Auto-casting. reinterpret_cast. Automatic stringification. Automatic type conversions across dissimilar types.
- all yes for scala. Infact, you can provide your own casts for any 2 types and import/export casts as you wish.
9. Nil/null as an overloaded semantic value (empty list, empty string, value-not-present) - Yes and No, Option[T] is generic. If you want to know if any container(including strings) is empty, you say container.isEmpty(). But not container == null.
10. Debuggers. Yes Scala has debuggers. At this point one has to ask - what is this guy smoking. If your language has a debugger it is a liberal language? WTF??
11. Bit fields - No
12. Implicit conversion operators (e.g. Scala's implicits). Sixty-pass compilers. Whole-namespace imports. Thread-local variables. Value dispatch. Arity-based function overloading. Mixed-type collections.
Yes, yes, yes for scala.
13. API compatibility modes. Advice and AOP. Convention in preference to explicit configuration.
These are fairly vague properties and you could say yes/no.
I recently converted a "liberal" perl project into "conservative" scala and the code size fell by an order of magnitude, but apparently I live in alternate universe where "conservative" languages are somehow more succinct.
This guy is just suffering from verbal diarrhoea and he gets way too much attention for his uninformed commentary. I haven't seen a more bogus classification in ages, it is quite amazing how he politicized a purely technical topic.
It is fairly clear what his issue is
1. He likes dynamically typed languages. You have to type less and lower error checking is tolerated by the community.
2. He is uncomfortable with more advanced PL concepts, cannot decipher compiler error messages when working languages like Haskell. He would much rather let the program run and crash with a run time stack, where he can jump in and examine the value or operation that caused the failure. The Haskell compiler error message makes him feel stupid and he does not like it. This also probably explains why he wants to dump clojure into conservative territory, too much of STM and Parallel Haskellish stuff going on.
3. He is not a big fan of java/C++.
There is nothing peculiar about the set of biases he has, in fact it is fairly typical. People who favor Java/C++ simply need high performance code that would need to be maintained/refactored for a long time. It is not a religious choice but a pragmatic decision in the face of constraints. I have never seen "conservatives" write build scripts in C++ or "liberals" write OS kernels in Ruby.
All the attributes he has described simply cannot produce the ordering of languages that he has conjured. In the only barely technical portion of the post he has contradicted himself soundly, but it doesn't matter because no one is paying any attention to that.
Gates was indeed a programming genius.
He wrote the BASIC interpreter and most of the software in Microsoft's early days. He also managed to publish an algorithm with Papadimitriou as an undergrad, while running Microsoft in parallel. http://www.sciencedirect.com/science/article/pii/0012365X799...
> Gates could not write the compiler tools himself
You are both underestimating Gates and overestimating how hard building a compiler/tool is.
3) was true until a few months ago. Or maybe its because I switched from a remote source repo mounted via Samba to a local flash HDD :-) I have been using Eclipse trouble free for a few months now, no issues whatsoever, except for some magic required during the initial maven setup.
4) Is an issue Scala outsiders complain about, but I have never seen this as an issue with people actually using Scala.
Build times are high compared to Java projects, though this could simply be because I am using scalac instead of fsc to build projects via maven. However, compilaton is incremental, so crazy build times should never occur in practice and the IDE highlights mistakes in less than a second.
Scala is far more object oriented than Java. So + is a method of the Int object and you can write 2.+(3) instead of 2+3. Methods are allowed to be operators, so that you can write 2+3 instead of 2.+(3). If _ is a separate token it represents an unnamed parameter, no more no less. In your specific case some_obj open_! translates to some_obj.open_.! It is not too difficult, you are just at week 1 of Scala.
As for language comparisons
1. C is simple/readable
It is way better than C in terms of readability. All
constructs in C are simple, but it takes a lot of C code to accomplish simple things. Also, how readable is
while(<star>d++ = <star>s++);
2. Python is explicit
The advantage of Scala here is static typing and performance and much better IDE support. Python code typically looks cleaner than Scala code, but I have been told that closures in Python are less than perfect. Python OTOH has no build time issues.
3. Clojure is more functional
Clojure is not more or less functional than Scala. There are varying definitions of "functional"-ness. However, the gold standard of a functional programming language is widely recognized as Haskell. Scala is far closer to Haskell than Clojure in this respect. Again the significant difference between Clojure and Scala is static typing, not functional-ness.
FileIterator("input.txt").map{_.split('@').last}.distinct.toFile("output.txt")
Lets compare it to the Python version. It looks much shorter, but many constructs are similar to what you wrote and it can be argued that the Scala code is merely a rearrangement of the tokens in the Python code. So let us explicitly call out the tokens/items I did not use in the Scala code, but you did in the Python code.
domains = [] domains.append(domain) out.close() infile.close() // I think you missed closing the input file, a handle leak bug
The map method encapsulates the construction of the output list and the FileIterator and toFile methods encapsulate the opening and closing of files. In particular, the Scala code hjas no handle leak bug. What functional languages are really good at is abstraction. map has abstracted away iteration and construction of an output list, while the file handling methods abstract away resource usage. As programs get bigger and more complex, this power of abstraction becomes increasingly powerful.
(Note that FileIterator and toFile are constructs that I wrote for myself a long time ago, differing constructs are available in the Scala std lib)