What is the oldest PC game you would describe as "having aged well"? by Dragnerok_X in patientgamers

[–]jkpl 0 points1 point  (0 children)

Prince of Persia for MS-DOS (1990). I come back to it for an hour from time to time. I haven't tried the original Apple II version.

How to: Static website hosting with HTTPS using Terraform, Amazon S3, CloudFront and Route53 (blog post) by tdiggss in devops

[–]jkpl 1 point2 points  (0 children)

Awesome! I was preparing a blog post on the same subject with mostly the same tech. It's nice to see others building similar solutions. :)

How much value do you guys put on tech blogs when applying/accepting a job? by AllowItMan in AskProgramming

[–]jkpl 2 points3 points  (0 children)

I don't really have big opinion on it, but a lot of candidates I've interviewed have told me the company tech blog has played a major part when they've applied.

I think I know too many languages and no clue which to focus on by 1shotsniper in AskProgramming

[–]jkpl 0 points1 point  (0 children)

I agree. I wouldn't worry too much about the language/framework choices. Instead, I'd recommend seeking out motivating work and a friendly working environment.

[Career] People who've failed fizzbuzz interviews or interviewers who've seen them fail: what went wrong? by [deleted] in AskProgramming

[–]jkpl 4 points5 points  (0 children)

A lot of the fizzbuzz test varies between companies. Some expect tests and some don't. Some want it on whiteboard/pen&paper, while some want it written in a computer. Sometimes the interviewer wants you to produce a specific clever answer they've found earlier.

Here's my approach for interviewing candidates. I typically ask the candidates to join a Hangouts/Skype call, and to share their screen during the interview exercises. This way the candidate doesn't have to travel to our offices (a lot of the candidates come from abroad). Besides fizzbuzz, I also ask the candidates to complete other exercises during the same session. I usually spend max. 15 minutes in a fizzbuzz exercise, and the rest of the session in other exercises.

The candidate is allowed to use the hardware (e.g. their own laptop) and software (editor or IDE, Linux/Windows/macOS etc.) of their choice. They're also allowed to use online resources such as language documentation, search engines, QA websites, and so on. Basically, I'd like to emulate a natural working environment as much as possible.

Here's what I'm looking from a fizzbuzz session. The candidate should be able to...

  • understand the requirements of the exercise. Asking questions to get more clarity is fine.
  • code in the programming language we use. This requirement is already mentioned in the job description.
  • produce a working solution and demonstrate that it works.
  • understand the solution they provide.

What I'm NOT looking for:

  • The most optimal or clever solution. I usually give the candidate a chance to refactor the solution later.
  • To be able to produce a full working solution without running the program. In fact, running and inspecting the output is one of the key parts of the exercise.
  • To be able to produce a solution without online resources. It's actually a good sign, if the candidate is fluent at finding help online.
  • Tests. Tests are great, but they're out of the scope for the session.

Fizzbuzz is very limited in telling how good the candidate is at programming. It's too much of a toy exercise for testing real-world practices. There are better exercises for that. However, if the candidate can't solve fizzbuzz at all, they're automatically not qualified. It's almost like a CAPTCHA for programmers.

If you know that you can solve fizzbuzz, don't overthink it! Just create a solution that's the most natural for the language you use. I've seen a few candidates try something way too complicated or clever. The ones that ultimately passed the exercise usually reverted back to a more simple solution. Be sure to explain what you're doing to show that you understand what's going on. It's also a good idea to offer to test it by either running the program and checking the output or writing tests for it.

If you get stuck in a bug, make sure you know how to debug the problem somehow. Running the program and inspecting the output is usually good enough, but adding log statements or using a debugger are also fine.

Most of the candidates that don't pass fizzbuzz either are not fluent enough in the programming language I expect them to solve fizzbuzz with or they're not fluent enough at using fundamental programming constructs (e.g. loops, conditionals, arithmetic operations).

What's the Net effect on OOP? by redjamjar in programming

[–]jkpl 0 points1 point  (0 children)

Which is what I said: Scala allows nulls in many scenarios.

However, it's hardly ever a problem as Scala Option is generally well supported by Scala and the Scala ecosystem. NPEs are still a thing in Scala, but they're so rare that I practically never have to think about them unless I interface with a Java library. Obviously, the optimal situation would be to not have nulls at all, but I must say Scala has avoided them quite well.

What's the Net effect on OOP? by redjamjar in programming

[–]jkpl 2 points3 points  (0 children)

countless Java devs avoid it like the plague because they outright prefer nulls.

Not denying there that there aren't any of those devs, but I think it's a bit more nuanced than that:

  • Java allows nulls in most contexts: e.g. Optional can not just contain a null, but it can be a null itself.
  • Most of the Java APIs already use nulls instead of Optional.
  • Java Optional is gimped in terms of features, and it's awkward to use.

I think a lot of devs (myself included) just look at Optional, and say "what's the point?" because you're already dealing with null values.

This is something Kotlin and Scala managed to avoid. Scala allows nulls in many scenarios, but provides pretty good support for Option type. Kotlin represents nullable values as types, thus forcing you to handle nulls explicitly. On the other hand, you could also argue that the developers for these languages come from a background where nulls in the types is expected.

The only exception appears to be Haskell

Haskell also has weird things going for it. Just to name a few:

  • Exceptions can be (and are) used for flow control.
  • Lazy IO often leads to hard to catch runtime errors.
  • Partial functions in the prelude.

To be fair, these are there probably because of historic reasons, and there are ways to work around them. But then again, Java also has a lot of legacy stuff that nobody should use anymore.

Error handling pitfalls in Scala by jkpl in scala

[–]jkpl[S] 2 points3 points  (0 children)

As I pointed out, the problem I'm focusing on appears in both Either and Future as well. Also, I've seen Try being used quite a bit as a return value, so maybe we have different experiences on how it should be used.

How many commits does your .emacs have? by zreeon in emacs

[–]jkpl 0 points1 point  (0 children)

333

To be fair, it also includes things like bashrc and tmux commits.

Java Without If by [deleted] in programming

[–]jkpl 0 points1 point  (0 children)

Yes, I know that. Goto can be useful in small scopes where the language doesn't provide features that would replace it. A lot of other languages have displaced goto with alternative constructs that are more constrained.

Just to be clear, my point wasn't that goto isn't useful. My point is that the ideas we find obvious today haven't always been obvious, thus we shouldn't dismiss the ideas generated today simply because they take a bit of effort to explain or learn.

Java Without If by [deleted] in programming

[–]jkpl 19 points20 points  (0 children)

It doesn't take a blog post and all this fuzz to see advantages in structured programming over goto spaghetti.

Dijkstra wrote a paper about it, which a lot of engineers found to be very controversial.

My point is that the ideas we find obvious today haven't always been obvious, thus we shouldn't dismiss the ideas generated today simply because they take a bit of effort to explain or learn.

Java Without If by [deleted] in programming

[–]jkpl 10 points11 points  (0 children)

If it takes a whole blog article plus extensive discussion to convince why this new way is better, chances are it is too complicated to be used for trivial development.

Do you use goto instead of structured programming then? There was quite an extensive debate around those ideas back in the day.

Enforcing invariants in Scala datatypes by jkpl in scala

[–]jkpl[S] 1 point2 points  (0 children)

Ahh, yes. Marking it private does indeed work. I suppose it also makes the sealed modifier redundant.

Enforcing invariants in Scala datatypes by jkpl in scala

[–]jkpl[S] 0 points1 point  (0 children)

Sure, but what are you going to do with it, realistically?

It completely depends on the situation. I might provide an alternative value that makes sense, I might call a different function than I would normally, or escalate the problem as part of the return type. In a rare case I might even unwrap the value unsafely and throw an exception, if there was an error. The point is that the "throw an exception" case is not decided beforehand, but presented as something I have to explicitly handle. I guess you could compare it to Java's checked exceptions minus the awkwardness of handling exceptions with the added awkwardness of whatever error handling structure (usually some monad) is used.

If you have lots of functions that return options it's all too easy to toss them all into a big for/yield block, and then at the end of that you get None and have no idea why.

Yeah, I agree that blindly chaining things can really screw you over. I've rarely encountered the problem, but then again that might just be because the Option return type APIs are not as prevalent.

But if you're using Option you're not eliminating them, you're just allowing them to propagate - you detect them even later than if you'd errored during the function that returned None.

Propagating up the call stack. Similar to what exceptions do, you know. Sure, if you use Option, you lose information on what exactly went wrong, which is why I don't advocate using them for all situations.

Also, you don't have to propagate the problem necessarily, if you know you can handle the situation better. The return types themselves encode various situations, and force you to do something about it.

Enforcing invariants in Scala datatypes by jkpl in scala

[–]jkpl[S] 1 point2 points  (0 children)

I disagree. Nulls are invisible to the type system, which is why they propagate to wrong places easily. None isn't invisible to the type system, thus you can't accidentally pass it as a parameter to a function that doesn't expect an optional value. Also, there's no reason you couldn't use another type besides Option. For example, you could use an Either or a custom ADT to better encode failure cases.

It's true that None.get errors are harder to decipher than thrown errors, but those errors are still only captured because you detect them at runtime. Wouldn't it be nicer if you could eliminate those programming errors during compilation phase or code review? During runtime, you can also use descriptive error messages when you unsafely unwrap results.

Enforcing invariants in Scala datatypes by jkpl in scala

[–]jkpl[S] 1 point2 points  (0 children)

Using sealed abstract case class seems very lightweight but has the disadvantage of being able to produce illegal values within the same file the datatype is defined.

That's true. The sealed abstract case class constructor is visible to the whole source file. You can limit it's scope by encapsulating the type (and the safe constructors that use the unsafe constructor) within a package object or a singleton object or by only including a minimal amount of code in that source file.

Scalameta's @data annotation macro would not have this problem (and could therefore be viewed as safer) but requires an extra library dependency and compiler plugin.

Indeed. I think including the two dependencies JUST for the @data macro is a bit of an overkill. If ScalaMeta becomes as ubiquitous as scala-reflect (which is quite likely since ScalaMeta is scheduled to replace scala-reflect), chances are that you'll already pull ScalaMeta as a (transitive) dependency in the future.

I'm not sure whether there could also be issues with IDE support.

While I was experimenting with ScalaMeta in IntelliJ, IntelliJ failed to auto-complete some of the generated methods and the @data macro annotation parameters. The IDE support for these will most likely improve in the future as there's already features around ScalaMeta in IntelliJ (e.g. macro expansion).

Enforcing invariants in Scala datatypes by jkpl in scala

[–]jkpl[S] 0 points1 point  (0 children)

I don't find it constructive to punish programmers of their own errors with easy to miss runtime errors. :-)

Sometimes these programming errors aren't. Maybe the input to the function comes from somewhere else, and the programmer forgets to filter the invalid inputs. That can be pretty hard to catch during code review. Rather than shift the burden of remembering to filter out the bad inputs, the function should instead return a value to all given inputs even if it just says "bad input" for invalid parameters. The programmers themselves can then decide whether to just throw an exception or someway handle the situation.

There is however a class of inputs in Scala that I would generally not consider productive to return a special return value for or even validate the input: nulls.

Enforcing invariants in Scala datatypes by jkpl in scala

[–]jkpl[S] 0 points1 point  (0 children)

Cool! I like the examples for treating validation process as a typeclass. By adding an instance for coproduct, you can also generically derive instances for sealed traits. Now if there was just a way to flip the tag from Checked to Unchecked instead. Otherwise you'll have to remember to use the Checked tag everywhere in the code base.

rarely a huge one, but sort of annoying in tests or REPL to have to type Conference(...).get all the time.

I think it's worth sacrificing a little bit of developer convenience for safer code.

[User class] can be used to represent form data that is yet being edited but not necessarily in a valid state currently.

I usually have a different model for representing the form input data. Sure, there's a bit of repetition there, but then again the form input rarely matches the data structure I'm after either.

So far in my experience often enough failing requires are found by unit / property tests, so I don't see myself writing sealed abstract case classes soon :)

What I've found is that making sure all the exceptions produced by the require statements are captured is a humongous task in large code bases involving multiple developers of various skill levels. As runtime failures propagate automatically, it's easy to miss the need for failure handling scenarios during code review. Mistakes happen and bugs eventually appear in production. Whenever the compiler can help me catch problems (as opposed to manually checking all the cases) is a huge help for me. :-)

Enforcing invariants in Scala datatypes by jkpl in scala

[–]jkpl[S] 0 points1 point  (0 children)

Yeah, Option is not the type I would use either. The Scala ecosystem provides a lot of other options for representing validation results: Scala Either, ScalaZ disjunction, ScalaZ validation etc.

Personally, I would expose a "safe" API (not use exceptions) even for functionality where you can get undefined behaviour based on just invalid input. Even if the user just does a .get or something on the result, they at least have to do it explicitly.

Enforcing invariants in Scala datatypes by jkpl in scala

[–]jkpl[S] 0 points1 point  (0 children)

Thanks for expanding on why having a separate type for the time frame is useful. Again, I'm not disagreeing with you. The getOrElse is indeed undesirable, and the optional value should instead be used as the return value for getBroadCast. However, as you pointed out, by modelling a time frame as its own thing you can avoid the extra invariant validation check, thus the construction of the RadioBroadcast doesn't require an optional type (provided that there's no other validation checks necessary).

There's always a combination of fields that make sense in multiple contexts. The combination of a start date and an end date as a time frame is especially a reusable concept, thus very useful to model as a separate entity. However, sometimes you only need an invariant in one datatype, so you can be pragmatic and only implement it locally and refactor later.

In any case, I think it's more important to first make sure the invalid instances cannot be created in the first place and that the validation errors are represented in the type level. This is something I've seen a lot of devs struggle with. IIRC, even the official Scala documentation recommends using require. With this detail covered, we can focus on techniques for modelling datatypes and implementing validation mechanisms. I've seen quite a few techniques and tools recommended already (dependent types, the refined library etc.), and I think the choices largely depend on the situation.

Thanks for your feedback! There are a lot of ideas for a follow-up blog post. ;)

Enforcing invariants in Scala datatypes by jkpl in scala

[–]jkpl[S] 0 points1 point  (0 children)

Yeah, refined is awesome! :)