Writing the post-condition for `is_leap_year` is (maybe) like trying to prove an axiom. A year is a leap year... because we say so, and we use *this algorithm* to say so. The only "good" test I can think of is what you'd get if you translate "The consequent average length of a calendar year is a better approximation of a true earth year than one might expect, given the simplicity of this algorithm, despite its constraints.", which has to do with *why* we choose the algorithm to be what it is.
@AlexandruCristianPopescu5 жыл бұрын
This guy really likes fizz buzz.
@krystofjakubek93762 жыл бұрын
A lot of these problems with preconditions were solved very nicely in closure with Spec. You can define arbitrary checks on any function arguments and return values in the function signature itself. These checks are performed every time the function is called but can be toggled off in release. Appart from being a documentation that must be true (the program wouldn't be able to run the function if it wasn't) it also lets you auto generate test inputs and expected outputs based on the requirements specified. I would love to see such feature added to more languages especially systems languages where safety sometimes can only be ensured (because of performance) via calling with proper arguments.
@virkony4 жыл бұрын
Was waiting for property tests at 59:30 up till 1:06:15... Especially at words like "grammar"... Something like: forall X: equivalent to forall X and forall E: equivalent to forall X: equivalent to forall X and forall Y: implies equivalent to forall X exists N: and
@chrissherlock17485 жыл бұрын
I’ve watched lots of this guys talks. He needs new material.
@JayJay-ki4mi4 жыл бұрын
"this guy" is paid to attend conferences and give the same talk. He has lots more material. Google is your friend.
@virkony4 жыл бұрын
Heh... 1:27:52 (test is a copy of code). I've been given another justification for having tests replicating source code: it is there to ensure that you think second time when you change one copy.
@paulfrischknecht39994 жыл бұрын
Once you realize that you never want to do anything but express your intention *and you just do it*, you become a much better programmer. Never play the compiler‘s role of expressing an idea in the instructions that are available. Imagine anything where possible, write the code that way, and implement it later.
@pacifico49993 жыл бұрын
44:09 Yeah that's clever, but it looks very inefficient
@alice_in_wonderland423 жыл бұрын
A lot of memory
@Carutsu8 жыл бұрын
While extremely powerful and succinct some times you cannot spare going over the list over and over again and the book-keeping of that is just too much.
@aMulliganStew4 жыл бұрын
40:13 Oh wow. Could it really have been that simple?
@tmuxor6 жыл бұрын
"Thank you very much"
@codeshot17956 жыл бұрын
Rather than use collation order (stupid idea), we can use semantic fallback (): import Control.Applicative import Data.Monoid -- [] models nondeterminism but our intention is corresponding sequences (a lattice) -- so we use ZipList to express that throughout and it's checked by the type system fizzes = ZipList $ cycle [Nothing, Nothing, Just "Fizz"] buzzes = ZipList $ cycle [Nothing, Nothing, Nothing, Nothing, Just "Buzz"] numbers = ZipList $ (Just . show) [1..] words = liftA2 () fizzes buzzes -- one way to apply inside an applicative choice = () chosen = choice words numbers -- and a different way result = (maybe "bug" id) chosen take 20 $ getZipList result
@codeshot17956 жыл бұрын
To deviate from Kevlin's form for an even better program: import Control.Applicative import Data.Monoid import Data.Maybe -- [] models nondeterminism but our intention is corresponding sequences (a lattice) -- so we use ZipList to express that throughout and it's checked by the type system fizzes = ZipList $ cycle [Nothing, Nothing, Just "Fizz"] buzzes = ZipList $ cycle [Nothing, Nothing, Nothing, Nothing, Just "Buzz"] numbers = ZipList $ show [1..] words = liftA2 () fizzes buzzes result = fromMaybe numbers words take 20 $ getZipList result
@tricky7786 жыл бұрын
I think this is a good solution: module Main (fizzbuzz, main) where import Data.List.NonEmpty (nonEmpty) import Data.Maybe (fromMaybe) import Control.Applicative (()) import Control.Monad (guard) import Data.Foldable (for_) fizzbuzz index = let isMultiple n = index `mod` n == 0 numeral = show index fizz = "Fizz"
@codeshot17956 жыл бұрын
There's a valuable improvement to make for the definition of "word", define and use foldlNonEmpty = foldl1 :: _ -> NonEmpty _ -> _ This is because foldl1 is partial for some Foldable instances and under refactoring the definition of substitutions could easily be moved away and the close association of the two lines lost in history. Defining and using foldlNonEmpty removes that issue with a function that is clearly associated with the definition of "word" due to its usage there and which constrains the function's applicability to where it's total. It would have been better if foldl1 were a member of class Foldable f => NonEmptyFoldable f since partial functions in type classes are clearly a pain.
@freddiepage61624 жыл бұрын
Surely the intension of prime numbers is "having" trivial factors, if they had non-trivial factors they wouldn't be prime
@tmuxor6 жыл бұрын
I got lost at the Erlang part..1:14:00
@rbettsx7 жыл бұрын
32:24 .. a redundant test? Test 5 is true if tests 1,3, and 4 are true. Also, if you rephrase tests 6 and 7: 'the ordinal position of every result that contains "Fizz" is divisible by 3' 'the ordinal position of every result that contains "Buzz" is divisible by 5' then tests 1,6, and 7 imply test 8, so you can get rid of that, too.
@randall1725 жыл бұрын
depends on exactly how you implement this. if you use if/else then yes. but if you use a switch statement then you should still have this test.
@JensRoland4 жыл бұрын
Came here to say this.
@julians.25972 жыл бұрын
testing whether that is the case is the point of a test^^. Never assume something logical will happen when writing your tests, you are writing them for when you think what's happening is illogical
@paulfrischknecht39994 жыл бұрын
Data + Interpretation* = Program. *when the Interpretation leads to a change of the Data
@jkd23775 жыл бұрын
hmmm... YES
@MathewGuest5 жыл бұрын
Revolutionary
@BryonLape7 жыл бұрын
The first while loop is exclusive of 101, unlike the following two examples.
@iggy147507 жыл бұрын
Bryon Lape Python's range() also has an exclusive upper bound. The other examples do have the same behavior.