reminds me i have a class that made us use java beans event listener based model-view-controller architecture with models that are literally stateful wrappers around pure functions
what we did was initialize a field to null then set it to what we actually want if you try accessing it while it's null
but then there's also a static method that lets you set it to something else which we actively used
the funny thing is this is a class about programming language concepts, where presumably we're looking at all this wacky java design pattern stuff to understand what motivates it, and the lectures are pretty good at exploring the motivations but the assignments... aren't
also i think the class is expected to not know that java has lambdas and method references because there's one place it seemed like we were supposed to use an enum or something to factor common logic out around processing data with two different methods and the assignment just said "you'll see a more elegant way to do this when we get to sml and lisp" like this literal 500 level class full of senior undergrads and actual graduate students has never heard of first-order functions before
@DLosc Singleton objects don't contain Holder objects, the static means that only one singleton instance is made, and Singleton doesn't have a Holder field at all
@DLosc Me too, although I like how Kotlin puts the companion object stuff inside the class itself
@DLosc Well, Scala creates an extra class for that companion object too, and that object is an actual object, unlike a static class that you can't really pass around. You can take that as an advantage or a disadvantage
@user *public static Singleton getInstance, not public Singleton
@UnrelatedString oh yeah there was also some constraint on when we can initialize a scanner for reading stdin to cooperate with the unit tests but we actually weren't encouraged to use a singleton-enforcing factory for that, despite that being something that actually does motivate a singleton-enforcing factory
like he literally told us that we have to initialize it after some other thing and that we have to not initialize multiple scanners but then gave some example code that uses a static variable in a method or something like why
Like for example in Pip, operators have an associativity, which right now is one of the three strings "L", "R", and "C". That seems like a classic use case for an enum. I'm just not sure it's worth the effort to switch.
Eh, for people like me who make lots of mistakes and are bad at testing, statically typed languages (with actually good type systems) are much easier when you have bigger projects
I feel the same way with JS, although I mostly grew to hate parts of it all at once and now it's just sort of been the same level of okayness for the last two or three years
JS is bad, but once you know how it works it just...works. There's not too much jankiness, compared to languages like Python.
It's not great for the first few years, but once you're used to it you get pretty fast at working around its issues. That's true for any language I guess, but JS's are just a bit less of an obstacle I think.
Python takes you on a date, talks to you for a while, and its issues slowly start to show up. JS shakes your hand, punches you in the face, and then is fairly normal from then on.
@user I have really come to appreciate the way that a statically typed language like Scala lets the IDE tell you exactly what type any variable is and what member functions it has. I just can't get over how much darn setup there is before you can run a simple Hello World program! (And how long sbt takes to start up each time.)
type-hinted python is just a dynamically typed language larping as a statically-typed language, ultimately combining the problems with both for marginal benefit
@UnrelatedString The worst is when you have a type hint referring to the class you're defining it in, so you have to say class Foo: def bar(baz: "Foo") ... to avoid it crashing
@RedwolfPrograms I think OOP is a very nice and intuitive paradigm, although I don't like that Java forces you to put everything in a class
@user Definitely. I don't know if it's a flaw or not, but any time y'all mention "factories" my eyes glaze over. I don't even know what that is, but every other language I've learned gets along fine without it, so to me it just sounds like jargon for the sake of jargon.
@DLosc ¯\_(ツ)_/¯ fwiw, I don't understand design patterns either, I assume it's the kind of thing you get used to after some professional experience, similar to Haskell programmers being unfazed by functors and gonads and stuff
...i think that time i was looking singletons up it was because i was wondering if there's some particular reason they actually need to exist and i think i did actually find that there are arguments against them
I'm mostly not a fan of teaching Java to new programmers because, at least to me, it feels like it's a language that died long ago and is only still being used in corporations, like Fortran or COBOL. Plus, it's still a little low level compared to JS or Python, and I could see that getting in the way of learning.
The things I ended up disliking about Julia were 1) it puts all those overloaded functions in the global namespace together, so it becomes nearly impossible to sort through the 138 different definitions of + to find the one you want, and 2) you can write code at the top scope but it's way less efficient or something? I don't remember the details.
@DLosc i feel like with stuff like arithmetic operators especially there's something wrong if you're actually overloading them instead of making them work with some kind of interface or typeclass
@user Well sure, because Java's newer. But it seems like it's very clearly going down the same path. And sure, it's not low level compared to C, but having to deal with types and C/Java sort of arrays seems like something that would just get in the way of learning.
@DLosc like, you could have an Addable interface/typeclass for things you can add and actually no that would restrict the kinds of addition you can define so yeah overloading is fine lol
I really wish I could use Kotlin or Scala for everything, but apparently Kotlin is considered a difficult language to teach so that idea got shot down :(
...i'd say i have no idea how kotlin could be difficult to teach but i actually haven't seen anything it has outside what i learned in the koans a month or two ago lol
I'd like to point out that Java has amazing IDE support in IntelliJ (I know JS does too, but static typing gives Java an edge here) so a lot of stuff is auto completed
@user i feel like most people should be much happier with explicit null checking and nullable types than with getting the infamous java nullpointerexceptions out of nowhere when they probably don't even know what a pointer is
I much prefer being able to define a function + (or maybe operator+) instead of a function with some name that doesn't contain the operator symbol that I then have to remember. That's one thing I dislike about Python's operator overloading.
Even Scala does this, to some extent: the apply method just automatically overrides the "function application operator" (if you can call it that). I wish you had an annotation or something like @thisFunctionOverrides() or smth
@WheatWitch idk about horrifying, but it is annoying for DSLs and stuff. Does make parsing easier, though
@UnrelatedString ¯\_(ツ)_/¯ It's quite handy when you want to define a constructor-like method, I just don't like the way you "override" that "operator"
@user sometimes you want to just pass indexing as a function and it's hard to want to just write a lambda that uses the square brackets syntax when you know there's a method you can use directly and it'll only take five minutes to look it up
Wouldn't it be cool if every concept in every language had to be accompanied by the longest and most unintuitive mathematical name for it one could find? /s
It determines the fixity solely based on the first character (and if the last character is :, it's right-associative). That makes life easier for the parser because it doesn't have to resolve other stuff first
i'm in a semantics class and i keep thinking about how a category-theoretical semantics might handle context and quantifiers and then i realize i don't know category theory
@UnrelatedString Just mumble something about "a monad of A is just a monoid in the category of endofunctors of A with product replaced by composition" and you'll be fine
@user it also makes it easier for a human to read an expression with user-defined operators if they can intuit the precedence and associativity without having to know what the operators do or reference their declarations
@user Maybe the page you linked isn't giving all the details, but it says "You can use any legal identifier as an operator," and then it gives an example where and is defined as a method of a class and immediately used as an infix operator...?
@DLosc The parser doesn't need you to define and at all, though, it'll still parse it correctly. The compilation error will just come later when it can't resolve and
compare haskell operators where you can usually guess precedence within a class of related operators based on what's most useful but then you want to use >>= and <$> together and sit for a minute wondering how that works
@DLosc You can't define unary operators like that, they're special. They have the same problem you dislike about Python: you have to define methods called unary_!, unary_~, etc. You can't make any identifier a unary operator, which I think is a good thing
I kinda dislike unary operators in general, despite their usefulness
@user Proposal: replace all unary operators with a single binary operator that performs different operations on its right operand depending on the value of its left operand /s
@DLosc However, since it has been previously established that you are masochist, you will have -language:postfixOps enabled, which means that w x y z will be parsed as w.x(y).z. But! If the next line has another a, it will be parsed as w.x(y).z(a). But! If there is another blank line or ; between w x y z and a, it will be parsed as w.x(y).z and then a, separately. I swear, Martin Odersky must've been drunk when he put that feature in
@WheatWitch That doesn't sound terrible, though
The fact that you have this much power is kinda scary. How is a human to remember so many fixities and stuff?
Java's type erasure is different, isn't it? It doesn't do monomorphization or whatever so you can't have two methods with one taking a list of strings and another a list of Files
I have a bunch of class properties that are initialized in a somewhat complicated but very uniform way. Since it is both error prone and a pain to maintain about 10 copies of this code I would like to abstract this.
Here is what the code looks like for setting one property:
if ( userConfigMapPat...
@WheatWitch May I ask if there's some reflection magic going on behind the scenes?
Are you using some kind of compiler plugin?
Because if there's a cast to some type parameter in there, then that should just be erased, and you can't instantiate something with a type parameter either, so you'd need a Class object or something, right?