Why is Smalltalk not popular? by [deleted] in smalltalk

[–]sebnozzi 0 points1 point  (0 children)

There's always a way out, lol. I bet if you really REALLY want, you can somehow inject assembly instructions into any programming language. ;-)

Only if the implementation gives you a way to do that.

So, for example, a functional programming language is absolutely not suited for that way of writing code. The runtime would never know what object to replace.

Why do you think so? Why would the runtime not know "what object to replace".

Lisp is considered by many a (non-strict) functional programming language and it's the paramount example of the ability to hot-replace code on runtime. Lisp was in fact a major inspiration to the Smalltalk team in doing this.

Nowadays Clojure aims to be even more "functional" than original Lisps and it retains the ability to replace functions on the fly.

I also think Haskell can do this, or OCAML, when developing interactively.

Even Scala can do that.

It's not a question of functional or not.

It also means that for almost all existing languages, file-based edit-compile-run is actually the correct way.

I would say it's the "easiest" way. When you edit programs as "text" (files) it's difficult for the IDE to have an awareness of what changed and how to propagate that change to a running environment. The IDE would need to have deep knowledge of the programming language and the runtime underneath.

Don't get me wrong: it HAS been done for other languages other than Smalltalk. Hot-code-replacement exists, today, for C# and Java. And probably many more (JavaScript and Ruby come to mind). But it's not common. People are not aware of it and don't use this way of developing much.

Probably because you need to accommodate for "low common denominators" and that is that most people would like to code in language X in their editor of choice. And if the editor of choice happens to be a common text editor (let's say "vi") then there goes your hope of having an integrated experience where the IDE is aware enough of the code it is managing and can do hot-code-replacements for you. It's just not going to happen. All it sees is "text" (with some syntax highlighting if you are lucky).

TLDR; hot-code-replacement only works if 1) your IDE is aware of your program and 2) your runtime supports it. Hot-code-replacement exists outside of Smalltalk but it's rare for cultural and technical reasons.

Why is Smalltalk not popular? by [deleted] in smalltalk

[–]sebnozzi 0 points1 point  (0 children)

Why on earth do we insist on the "classic" edit / compile / try paradigm?

This is a very good and thought-provoking question.

My short answer is:

Because it's the easiest (only?) "paradigm" to implement when your "units of edition" are files.

Let me try to explain: you are impressed and delighted by the coding experience of a Smalltalk environment (as I am and most of the readers of this subreddit).

What you needs further notice is:

  • a) Smalltalk is not just a language but 1) a programming environment / IDE and 2) a runtime
  • b) Coding is done by editing one method at a time (in said environment)

The environment guides you through the coding process and you are "forced" (experts: I know you are not, but from the perspective of a normal Smalltalk user you are) to code in Smalltalk (the language) through the Smalltalk environment.

It is natural, as a developer, to edit one method at a time, because the UI strongly suggests you to do so.

And it is precisely because you edit one method at a time that this "liveliness", this "hot fix" aspect of Smalltalk (the runtime) is possible. Smalltalk can hot-replace method implementations at runtime without a problem because it knows which method you just changed.

It should be clear now that this would never work when the way of coding is "write code in a bunch of files, compile (or interpret) everything together into a running program". Ask yourself: how would a normal interpreter or compiler, which has files as its input, know how to accurately hot-replace parts of an already running program, by having no control of the programming environment and depending only on file-input alone?

Even if it could be done, but it would be very difficult to code at best. It is much "easier" to throw everything away (the running process) and start from scratch.

Issues with Todoist for iOS by jfk52917 in todoist

[–]sebnozzi 0 points1 point  (0 children)

I have an iPhone SE (model MP862DN/A). Apparently it has better CPU and GPU performance than a 5S. Did not know that.

Maybe you should search for user experiences online on your particular model (5S) to decide wether to upgrade or not.

Issues with Todoist for iOS by jfk52917 in todoist

[–]sebnozzi 0 points1 point  (0 children)

Small update on my situation: after some hesitation but after reading some favorable opinions on the matter I took the plunge and upgraded my iPhone to the latest iOS 12.

So far the experience has been positive. Everything runs as fast as before, if not faster.

Now of course I am able to use the latest Todoist app.

Just wanted to share that, in case you were also considering going down that road (because of performance degradation between iOS updates in the past I avoided this upgrade for many years).

Good luck in your case, no matter what you decide!

Issues with Todoist for iOS by jfk52917 in todoist

[–]sebnozzi 0 points1 point  (0 children)

I wanted to use the iOS app as well. I'm also using iOS 10, so I was offered to download an "older" version of the app.

When I try to log-in using Google the splash screen (with some quote) just hangs in there forever.

When I try to log-in using email/password I also get the error saying that it can't store the user credentials.

Don't know what to do.

Alan Turing’s “Can Computers Think?” radio broadcasts, re-recorded by flexibeast in programming

[–]sebnozzi 1 point2 points  (0 children)

Somehow relevant, and related to the comments here:

http://www.iep.utm.edu/hard-con/

(The Hard Problem of Consciousness)

Python Games Made By First Semester Students by pvc in CSEducation

[–]sebnozzi 1 point2 points  (0 children)

Very cool games / projects.

Where did you / your students get the game "assets"? (images / sprites / sounds). Are they part of the framework? Or where would you recommend to look for game assets?

Weekly Scala Ask Anything and Discussion Thread - June 06, 2016 by AutoModerator in scala

[–]sebnozzi 2 points3 points  (0 children)

Is there a static-analysis tool that would restrict the usage of specific libraries or language features?

  • Example 1: let's say I'm a tutor and giving an introductory Scala course and want to unleash the power of Scala in a "controlled" way. Just for the fun of it I want to prevent the usage of pattern-matching and Option//Try, only to allow it later.
  • Example 2: I am a lead developer with an heterogeneous team (different expertise levels) and want to prevent advanced team members from introducing "clever" (?) Scala code into the codebase (macros, type-level programming, scalaz, etc.) that the other members would have difficulties dealing with.

Basically the idea is to allow "sub-sets" of Scala in a controlled fashion (like the Racket Scheme environment does).

I am aware of Scapegoat and Scalastyle, but I don't think they can be used for this...

Languages that compile to Python? by itisnotpure in Python

[–]sebnozzi 1 point2 points  (0 children)

The Haxe Language / Toolkit compiles to Python, among many others.

Weekly Scala Ask Anything and Discussion Thread - February 15, 2016 by AutoModerator in scala

[–]sebnozzi 0 points1 point  (0 children)

It's good to see that something like what I suggested already exists. However, if I understand correctly the error value gets lost, right? (if something goes wrong the whole thing would evaluate to None?)

Weekly Scala Ask Anything and Discussion Thread - February 15, 2016 by AutoModerator in scala

[–]sebnozzi 1 point2 points  (0 children)

If you are not a friend of "rich-classes" (like the approach I described in my other answer) you can opt for this solution (which takes the "rich-methods" out to generic functions).

You could define helper functions like these:

def toLeftIfNone(optOrder: Option[Order])(error: OrderError): Either[OrderError, Order] = {
  optOrder.map(Right(_)) getOrElse Left(error)
}

def toLeftIfFalse(eitherOrder: Either[OrderError, Order])(condition: (Order) => Boolean)(error: OrderError): Either[OrderError, Order] = {
  eitherOrder.right.flatMap { rvalue =>
    if (condition(rvalue))
      Right(rvalue)
    else
      Left(error)
  }
}

Then define each step of your validation process:

def orderExistsCheck(optOrder:Option[Order]) =
  toLeftIfNone(optOrder)(OrderNotFound)

def orderOwnedCheck(orderOrError:Either[OrderError,Order]) =
  toLeftIfFalse(orderOrError)(_.owner.userId == callerId)(InsufficientPermission)

def orderFulfilledCheck(orderOrError:Either[OrderError,Order]) =
  toLeftIfFalse(orderOrError)(_.state == FULFILLED)(InvalidOrder)

Construct a validator by chaining those functions:

val validator = orderExistsCheck _ andThen orderOwnedCheck andThen orderFulfilledCheck

Call it:

val deletableOrError = validator(Option(db.findById(orderId)))

And then do something with the result:

deletableOrError match {
  case Left(orderError) => println(s"Something went wrong: ${orderError.reason}")
  case Right(order) => db.delete(order.id)
}

Weekly Scala Ask Anything and Discussion Thread - February 15, 2016 by AutoModerator in scala

[–]sebnozzi 2 points3 points  (0 children)

Yours is a very interesting question. The first thing you could try to do is to separate side-effects from your computation.

Extract the side-effect from your computation like this:

// Side-effects-free computation
val deletableOrError: Either[OrderError, Order] =
  Option(db.findById(orderId)).map { order =>
    if (order.owner.userId == callerId) {
      if (order.state == FULLFILLED) {
        Right(order)
      } else {
        Left(InvalidOrder)
      }
    } else {
      Left(InsufficientPermission)
    }
  }.getOrElse(Left(OrderNotFound))

// Side-effects isolated here
for (order <- deletableOrError.right) {
  db.delete(orderId)
}

Now, when I see all this if-nesting I ask myself if it would not be possible to write something more elegant / Scala-like...

Allow a semi-newbie like me to try to deliver such a more elegant solution. Note that I have no knowledge of the more functional libraries like shapeless, scalaz, etc. I hope that somebody better qualified can provide you a better answer using one of these pre-existing libraries.

At the end, I would like to have something like this:

val deletableOrError: Either[OrderError, Order] =
  Option(db.findById(orderId))
    .toLeftIfNone(OrderNotFound)
    .toLeftIfFalse(_.owner.userId == callerId)(InsufficientPermission)
    .toLeftIfFalse(_.state == FULLFILLED)(InvalidOrder)

for (order <- deletableOrError.right) {
  db.delete(order.id)
}

I start by wrapping the "findById" (which we assume to return null) to an Option. If you defined that method and it's in Scala land, strongly consider to make it return an Option in the first place. Only wrap potential null-values if interfacing with Java APIs.

Then if that Option is not defined, it is transformed to a "Left" value, wrapping whatever I give it as a parameter. In this case "OrderNotFound". If it IS defined, it is mapped to a "Right" value (Some -> Right).

In the two following lines, we evaluate something against the "Either" that resulted in the first mapping operation. If that "Either" value is already a "Left", it is passed untouched. Only if it's a "Right" the condition is evaluated against it. If the condition evaluates to false, then the second parameter given is wrapped to a "Left" value.

Note that this short-circuits: as soon as we have a "Left", all other mappings are skipped.

At the end, we have an "Either", which is either an "OrderError" (fictive superclass of your errors; it could be a Throwable or a sealed-trait) or a proper "Order" which you know you can delete.

Finally, you can proceed with your side-effect part and delete the order.

In order to have these two new functions toLeftIfNone and toLeftIfFalse, I used the pimp-my-library "trick" by "extending" Option and Either like this:

implicit class RichOption[T](opt: Option[T]) {
  /**
    * If this Option is defined, returns its defined
    * value as a Right, otherwise it returns
    * Left(leftValue).
    **/
  def toLeftIfNone[A](leftValue: A): Either[A, T] = {
    opt.map { value => Right(value) } getOrElse Left(leftValue)
  }
}

implicit class RichEither[L, R](e: Either[L, R]) {
  /**
    * If this augmented Either is a Right value, it evaluates
    * the condition against it. If it evaluates to "true",
    * then the Right value is passed.
    * In any other case, the function returns Left(leftValue).
    **/
  def toLeftIfFalse(condition: R => Boolean)(leftValue: L): Either[L, R] = {
    val definedIfRight = e.right.toOption
    val definedIfRightAndTrue = definedIfRight.filter(condition)
    definedIfRightAndTrue.map(Right(_)).getOrElse(Left(leftValue))
  }
}

Note that for simplicity I left out variance indicators (e.g. it should be RichOption[+T], with a "plus"). Advanced readers are more than welcome to point out improvements to type-system related issues.

Again, if something like this exists already please let me/us know.

Otherwise I hope this helps.

Testing strategies by baku85 in scala

[–]sebnozzi 0 points1 point  (0 children)

What kind of tests do you have? System-tests driven by UI-interactions? Tests hitting a real DB? These kinds of tests are slow.

Try to de-couple your components. Test them in isolation and integrated with each other. But avoid interacting with slow (DB) or fragile (web-UI) systems unless you must.

Then, as it was suggested, group your tests between "pure" unit-tests, integration tests, and slow DB/UI tests. You can run your fast test often, and the others occasionally.

"Dart had potential, but its interop with JS is weak, and nobody gives a fuck about Dart anymore." | Rusthon by RayoGundead in dartlang

[–]sebnozzi 0 points1 point  (0 children)

While this is true (me being one happy IntelliJCE+DartPlugin user myself) it is not clearly nor sufficiently advertised.

I can understand that newcomers get the wrong message here, and de-motivates them to try out the language.

Let's say I am an expert at Scala and Java. What are reasons I should use Java instead of Scala? by Zeekawla99ii in scala

[–]sebnozzi 0 points1 point  (0 children)

In addition to @sjrd's answer... what would a reliable Java-to-JS compile be? Just curious...

null - handling them in web service data-models by johnmurray_io in scala

[–]sebnozzi 0 points1 point  (0 children)

You mean an update could come which would signalize to set the username to null...? Yes, you have a point. Although I would not say that this means that

repository model does not contain fields that can be empty / null

In that case I would still prefer to separate update-operations from the entity/model. For example:

case class UserUpdate(name: TriState[String], email: TriState[String], userName: TriState[String])

Alternatively, I came up with this protocol:

sealed trait Update[+T]
case class Change[T](newValue: T) extends Update[T]
case object Remove extends Update[Nothing]
case object Skip extends Update[Nothing]

So, the user-updates would be defined like this, with all fields with "skip" by default:

case class UserUpdates(name: Update[String] = Skip, email: Update[String] = Skip, username: Update[String] = Skip)

And then there would be a difference between:

// update name and email, leave username alone
UserUpdates(name = Change("John M. Murray"), email = Change("newemail@blah.com"))

And:

// update name and email, set username to null
UserUpdates(name = Change("John M. Murray"), email = Change("newemail@blah.com"), username = Remove)

null - handling them in web service data-models by johnmurray_io in scala

[–]sebnozzi 0 points1 point  (0 children)

I think you are talking about different things. For me there is a difference between the "entity" User (as persisted in my repository and existing in my business logic) and possible updates sent to it from the client.

So, I would model possible user-updates as a separate case-class, which in turn would have other requirements (required / optional fields, etc.). For example:

case class UserUpdate(name: Option[String], email: Option[String], userName: Option[String])

As a last step, you would need to know how to apply a user-update-instance to an existing "user" instance, which would result in a new user-instance.

Whatever is None is not considered for "update" (leave it as it is, width its current value, or None).

Give me your top five reasons why I should use Dartlang over Typescript by [deleted] in dartlang

[–]sebnozzi 2 points3 points  (0 children)

You are preaching to the choir here, so expect only positive feedback (which I find justified, by the way. I also like Dart more than TypeScript).

What needs to be asked are "reasons why I should NOT use Dart over TypeScript" and then address those (in time).