intro-to-scala's People
Forkers
chanjk hanmoi-choi felipeeflores cloud-on-prem ttcao stilianouly njskater benhutchison wangyunlongau gerardo kuangyixing terry-dai frediy shaun-whitely tomcjohn xiangdao ninth-dev btheunissen wsutina linliuly lukestephenson hamxashahid petern-sc void-kuangyi bjarkevad tkjohn saisea doudou1212 trammel lukestephenson-zendesk ntdesilv iranianpep writerdean eunicecompra chawon confman recklyss yaweiya dylanpinn shardulsrivastava wayneellery tttcao natalieytan melonq 595972434 cshonig zendesk alonsoir bhargysh brunoscaglione linchen2chris shanyueguo agiledigital-labs sanjivsahayamrea anita-miller liyanlance djoepramono karenchang-zendesk airvin jessiezd quelgar jayhjkwon nareshmiriyala tuan-org climber2002 george-wilson-rea monkey214207 stefan-vrecic-pro alizand1992 ashokkumar ssanj davidbkemp c6aiintro-to-scala's Issues
add example output to ExceptionExercises#createValidPeople2
Exceptions2EitherExercises does not need an hour fifteen
I think I can complete the Exceptions2EitherExercises
in 45 mins similar to the ExceptionsExercises
. The content of Exceptions2EitherExercises
is very similar to ExceptionsExercises
so there is much less overhead in going from one to the other - only translating Exceptions -> Eithers.
This should free up 30 mins which we can use somewhere else; maybe on the
TryExercises
or LogParser
?
Deprioritise zip exercises.
I think zipping isn't very important in this course. If we de-prioritise it (put it in the bonus section), we can bump getNames
, getAdults
and reverseList
, which are exercises to rewrite imperative code in a functional way. I ran this recently and found that it was valuable.
Or we could introduce collect
here to prepare students for Exception
and Either
exercises.
Move case objects out of TrafficLight object in ADT definition.
This will simplify things for people.
Add more exercises to Day 1.
I think we need to add at least 1 hard exercise to Types and List.
Some things we could consider adding:
- Tuples (Intro)
- Creating your own case class (Types)
Introduce `flatMap` in `OptionExcercises2`
should we introduce flatMap
on findJobIdByHumanId
.
At this point people understand what an Option
type is and how/when to use it. findJobIdByHumanId
is a very good example of how you combine two Option
s. The IDE suggest that you should use flatMap
instead of map.flatten
.
The next exercise findJobByHumanId
has the same intuition. We could introduce it here to show the difference.
Should we add currying to day1?
Introduce curried functions
This is needed to explain foldLeft
Check nonEmpty in LogParser comment
Presentation on for-comprehension after OptionExercises2?
Pattern matching - Add note on constructors for each exercise
Add more examples to Option1Exercises.mkTrafficLight
/**
* scala> mkTrafficLight("red")
* = Some(Red)
*
* scala> mkTrafficLight("bob")
* = None
**/
def mkTrafficLight(str: String): Option[TrafficLight] = ???
should also have:
/**
* scala> mkTrafficLight("red")
* = Some(Red)
*
* scala> mkTrafficLight("green")
* = Some(Green)
*
* scala> mkTrafficLight("yellow")
* = Some(Yellow)
*
* scala> mkTrafficLight("bob")
* = None
**/
def mkTrafficLight(str: String): Option[TrafficLight] = ???
Teach some basic Cats?
- sequence
- traverse
I think we could add these to end of Day 1
Add test for `createValidPeople2` to test no exception is thrown?
ListEx: Fill out body of map/filter/fold exercises with imperative solution like in bonus exercises?
Consider using immutable Docker Image Reference
Consider using immutable docker image reference to ensure better security and stability.
intro-to-scala/docker-compose.yml
Line 5 in 9ec17db
In this case, it can be:
hseeberger/scala-sbt@sha256:83a79dfd0989f1e8404a9731673457139b6d9fceff2fdf7a3e27c3e17d5eb4d6
ExceptionExercisesTest
For the createPerson
function the assertions need to be fixed for the tests:
-
"should return Person if supplied a valid name and age"
The test should assertPerson("Fred", 32)
-
"should throw an EmptyNameException if the name supplied is empty"
The test should assert"provided name is empty"
-
"should throw an InvalidAgeValueException if the age supplied is not an Int"
The test should assertInvalidAgeValueException
is thrown instead ofInvalidAgeRangeException
List: Do not cover covariance.
Possibly confusing and distracting?
When do we do the for-comp exercise
The for-comp
exercise needs to be added to the README.
Add FP concepts into cheat sheet
- Add FP concepts into cheat sheet such as Functor and Monad (or create a separate cheat sheet)
Remove mkTrafficLightOrNull exercises from NullExercises
Remove mkTrafficLightOrNull exercises from NullExercises:
def mkTrafficLightOrNull(str: String): TrafficLight = ???
def mkTrafficLightOrNullThenShow(str: String): String = ???
as these are covered by the Person exercises:
def mkPersonOrNull(name: String, age: Int): Person = ???
def mkPersonOrNullThenChangeName(oldName: String, age: Int, newName: String): Person = ???
Remove validPerson from ExceptionExercises
Should we remove validPerson from ExceptionExercises?
def createValidPeople: List[Person] = ???
and just use:
def createValidPeople2: List[Person] = ???
We are trying to demonstrate that you have to use hacks when you use Exceptions as values.
Create sort exercise for List
Exceptions2EitherExercises - getAge has an off by one problem.
I think getAge
should not allow 0
.
If it does, then createValidPeople
returns Arturo as well, which violates the test.
Add presenters names against schedule
showLogMessage test is incomplete.
Upgrade to Scala 2.13
Will help in simplifying type signatures of collections
Depends on Delight and ScalaTest to be upgraded first
IDE support docs
Remove takeWhile and tests
Move Applied material into a separate code base
Add more examples to Option1Exercises.mkTrafficLightThenShow
This:
/**
* scala> mkTrafficLightThenShow("red")
* = "Traffic light is red"
*
* scala> mkTrafficLightThenShow("bob")
* = "Traffic light `bob` is invalid"
*
* Hint: Use `mkTrafficLight` and pattern matching.
*
* You can pattern match on `Option` using its two constructors `Some` and `None`:
*
* ```
* optSomething match {
* case Some(a) => // do something with `a`
* case None => // do something else
* }
* ```
*/
def mkTrafficLightThenShow(str: String): String = ???
should change to:
/**
* scala> mkTrafficLightThenShow("red")
* = "Traffic light is red"
*
* scala> mkTrafficLightThenShow("yellow")
* = "Traffic light is yellow"
*
* scala> mkTrafficLightThenShow("green")
* = "Traffic light is green"
*
* scala> mkTrafficLightThenShow("bob")
* = "Traffic light `bob` is invalid"
*
* Hint: Use `mkTrafficLight` and pattern matching.
*
* You can pattern match on `Option` using its two constructors `Some` and `None`:
*
* ```
* optSomething match {
* case Some(a) => // do something with `a`
* case None => // do something else
* }
* ```
*/
def mkTrafficLightThenShow(str: String): String = ???
Add timestamp to WARN line in logfile.csv
Change changeName in TypesEx to be changeAge.
Currently people can do .copy(newName)
and it'll just work because name
is the first param.
Remove `curriedAdd`
curriedAdd
in IntroExercises may not be very useful because we don't use currying later on.
Feels like a distraction.
Add SimpleReport and instructions to project
~testOnly *TryExercisesTest -- -C fundamentals.SimpleReporter
Finish unit tests
Do we need Wallet in TypeExercises?
We cover most of what Wallet does in TypeExercises with Person. Do we need to double up?
//Type -> String
def showWallet(wallet: Wallet): String = ???
is the same as:
def showPerson1(person: Person): String
def showPerson2(person: Person): String
//immutable copy
def purchase(cost: Double, wallet: Wallet): Wallet = ???
is the same as:
def changeName(newName: String, person: Person): Person = ???
TyperExercises.showTrafficLightStr extension
To support the extension of TyperExercises.showTrafficLightStr:
We have a new traffic light called Flashing, with a frequency, e.g. "flashing 20", "flashing 100"
Extend
showTrafficLightStr
that you have just implemented above to support this new functionality.
should we mention:
Hint: String.split and pattern match on Array
or were you thinking of introducing regexs here?
"""flashing\s\(d+)""".r
When do we introduce `case` in `map`/`filter` etc?
First exercise that uses it is showEveryNthPerson
Flashing with Frequency in TypeExercises
Adding a Flashing with a frequency to TypeExercises makes this a little too complex as:
- We need to explain Regex matching or
- Explain splitting and matching on Array.
If we get rid of the frequency this exercise will be much easier and we can easily demonstrate the compile-checked exhaustiveness.
/**
* We have a new traffic light called Flashing, with a frequency, e.g. "flashing 20", "flashing 100"
*
* Extend `showTrafficLightStr` that you have just implemented above to support this new functionality.
*
* Use a test driven approach to implement this new functionality.
*
* scala> showTrafficLightStr("flashing 20")
* = "The traffic light is flashing with a frequency of 20"
*
* scala> showTrafficLightStr("flashing 100")
* = "The traffic light is flashing with a frequency of 100"
*
* Hint: Use flashing regex and pattern matching or
* use `.split(" ")` and pattern-match on `Array("flashing", frequency)`
**/
val flashing = """^flashing\s(\d+)$""".r
Partially completed (fill in the blank) for comprehension and pattern matching
IntroEx - Tuples - Add pattern matching hint or note
Change `NullExercises` to disallow changing to empty name in `mkPersonOrNullThenChangeName`
- For simplicity, let's allow changing to an empty name, like:
Change this like we did for Options.
Change getUnknowns to getErrors
In LogParser so getErrors can be reused in showErrorsOverSeverity.
Add explanation of class vs object, etc.
I think we can explore more of the language in day 1, because day 1 is a little short.
ListExercises.min implementation is unsafe
The current implementation of:
def min(nums: List[Int]): Int
uses a INT.MInValue as default.
I guess this is because we haven't covered Option
yet?
Separate Option, Either and Try into different levels.
This will make it easier to run tests and see the progression better.
Add exception exercises to level03
Calculating `min` is weird.
In reality I would use NonEmptyList.from(list)
and then reduce
on the NEL.
But here people have to fold on the tail
and it feels so odd.
Maybe we can rewrite this into an exercise where we concatenate a bunch of strings together?
Or to reverse a list?
Add more list excersies
- list.drop
- list.take
- list.last
- list.reverse
- Range
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.