Lisplog

Blogging in Lisp

Search

Feed Aggregator Page 652

Rendered on Tue, 29 Sep 2020 02:03:40 GMT  newer latest older 

Float types with inputs?

via Elm - Latest posts by @cmanallen C. Allen on Tue, 29 Sep 2020 01:04:29 GMT

Hi,

I’m trying to make a simple money app with Elm 1.19.1. When a user enters a value in the input I’m setting that value on the model. I’m also re-painting the input with the value that was just entered. Meaning if the user provided something invalid then it will default to something other than what they entered.

This works great for integers. But for floats something like “32.” instantly breaks because the period is removed by the update function (String.toFloat |> Maybe.withDefault model.value). I’m wondering what is the best way to manage this?

type Model alias = { value : Float }

type Msg = SetValue String

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        SetValue val ->
            ( { model | value = val |> String.toFloat |> Maybe.withDefault model.value }, Cmd.none )

view : Model -> Html Msg
view model =
    input [ onInput SetValue, value model.value ] [ ]

I don’t want to store it as a string on the model because I feel like I lose that free validation. But I don’t know. Whats the best practice here?

logBase 10 erroneous

via Elm - Latest posts by @jreusch Joshua on Mon, 28 Sep 2020 21:05:54 GMT

Basics.logBase is implemented as log number / log base, where log is just Math.log from Javascript. The rounding errors you are seeing comes from the floating-point division happening here.

There also exists Math.log10 in Javascript, which yields better results, but does not exist in Internet Explorer. As always, there already exists an issue matching your problem, and a pull request proposing to use said javascript function.

Zach Beane: New SBCL 2.0.9 behavior breaks some stuff

via Planet Lisp by on Mon, 28 Sep 2020 18:29:40 GMT

The latest SBCL handles slot :initform and :type options in a new way. It’s mentioned in the release notes.

minor incompatible change: the compiler signals a warning at compile-time when an initform of T, NIL or 0 does not match a STANDARD-CLASS slot’s declared type._

Sounds pretty benign, but it breaks dozens of projects in Quicklisp. (To be fair, most of the failures are caused by a small number of core systems on which many other systems depend.)

Here’s an example of the new behavior:

(defclass foo ()
  ((name :type string :initform nil)))

With the above defclass form, SBCL 2.0.9 will signal a warning at compile time:

; processing (DEFCLASS FOO ...)

; file: foo.lisp
; in: DEFCLASS FOO
;     (NAME :TYPE STRING :INITFORM NIL)
; ==>
;   (SB-KERNEL:THE* (STRING :SOURCE-FORM NIL :USE-ANNOTATIONS T) NIL)
; 
; caught WARNING:
;   Constant NIL conflicts with its asserted type STRING.
;   See also:
;     The SBCL Manual, Node "Handling of Types"
; 
; compilation unit finished
;   caught 1 WARNING condition

This compile-time warning means “failure” as far as loading with ASDF is concerned.

If you have both :type and :initform in your slot definitions, and you want to be compatible with the latest SBCL, make sure the initform type matches the slot type. If you want to use NIL as the initform, one easy option is to set the type to (or null <actual type>).

logBase 10 erroneous

via Elm - Latest posts by @stevensonmt Stevensonmt on Mon, 28 Sep 2020 19:43:16 GMT

Yes, there are other ways to approach my particular problem but the link you provided includes the method I’m using. My specific use case is orthogonal to the problem of a potentially fundamental bug in a basic arithmetic function. The appearance of a pattern suggests to me that the error is not simply “floating point math is quirky” but rather something that can be fixed. I would create an issue on github to address this if others can confirm the bug.

New SBCL 2.0.9 behavior breaks some stuff

via Zach Beane Common Lisp by on Mon, 28 Sep 2020 18:29:40 GMT

The latest SBCL handles slot :initform and :type options in a new way. It’s mentioned in the release notes.

minor incompatible change: the compiler signals a warning at compile-time when an initform of T, NIL or 0 does not match a STANDARD-CLASS slot’s declared type._

Sounds pretty benign, but it breaks dozens of projects in Quicklisp. (To be fair, most of the failures are caused by a small number of core systems on which many other systems depend.)

Here’s an example of the new behavior:

(defclass foo ()
  ((name :type string :initform nil)))

With the above defclass form, SBCL 2.0.9 will signal a warning at compile time:

; processing (DEFCLASS FOO ...)

; file: foo.lisp
; in: DEFCLASS FOO
;     (NAME :TYPE STRING :INITFORM NIL)
; ==>
;   (SB-KERNEL:THE* (STRING :SOURCE-FORM NIL :USE-ANNOTATIONS T) NIL)
; 
; caught WARNING:
;   Constant NIL conflicts with its asserted type STRING.
;   See also:
;     The SBCL Manual, Node "Handling of Types"
; 
; compilation unit finished
;   caught 1 WARNING condition

This compile-time warning means “failure” as far as loading with ASDF is concerned.

If you have both :type and :initform in your slot definitions, and you want to be compatible with the latest SBCL, make sure the initform type matches the slot type. If you want to use NIL as the initform, one easy option is to set the type to (or null <actual type>).

Init a task in a module + avoid circular import?

via Elm - Latest posts by @Yannick971 Yannick on Mon, 28 Sep 2020 18:47:22 GMT

That is good advice… thank you!

Can the compiler skip virtual DOM?

via Elm - Latest posts by @evancz Evan on Mon, 28 Sep 2020 16:07:54 GMT

I should add, I do not actually know what Svelte is doing specifically. I would personally be interested in seeing a little breakdown of their key techniques. Maybe there are lessons that could be applied in Elm. Would be very curious to understand more!

And maybe it’s something that could be explored in the style of elm-optimize-level-2 so that it is not blocked on compiler releases or anything.

"fold" animation in elm-css

via Elm - Latest posts by @system system on Mon, 28 Sep 2020 15:46:13 GMT

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.

Elm-music-theory: A toolkit for musical ideas

via Elm - Latest posts by @duncanmalashock Duncan Malashock on Mon, 28 Sep 2020 13:21:17 GMT

I was fifteen and on a trip with my family in Minocqua, Wisconsin when I heard “Slumber Song” by Glenn Miller on a local radio station one night.

I had never heard music like it before. It was intelligent and organized, with great warmth and sensitivity. It sparked my interest in the technique I now know as sectional harmony, in which most of the melodies in a piece are harmonized into multiple parts and played together by groups of instruments. In this case, these are the trumpet, trombone, saxophone, and vocal sections.

The techniques of jazz arranging

Many years later, wanting to apply these techniques to my own music, I started taking private lessons from a jazz arranger. As I began to understand the various concepts that made up this obscure and specialized field, like voicing types, approach techniques, and available tensions, I saw how much attention and mental energy is required in order to apply them.

For instance, in any given situation when harmonizing a melody, an arranger generally has to ask themselves the following questions:

  • What techniques are available for harmonizing the current melody note?”
  • “Which of the options that these techniques could produce would fit the conventions of the musical style I am working in?”
  • “Which of the valid options is the best choice in this situation?”

None of these questions can be answered simply. Students work for years to improve their facility with arrangement techniques and develop their musical judgment.

The question of the best choice requires a musical sensibility to answer, but the others are questions of generating musical structures and validating them against certain criteria. Could those parts of this work be automated for an arranger’s benefit?

Announcing elm-music-theory v1.0.0

Today I’m happy to announce the initial release of elm-music-theory , a new music theory library for the Elm language and the result of my work to answer this question.

elm-music-theory allows you to work with musical concepts like pitches, intervals, chords, keys, and scales. This includes (but is not limited to) the tasks involved in arranging sectional harmony.

For instance, if you were an arranger trying to harmonize the melody to “Slumber Song”, you could use elm-music-theory to generate a list of chord voicings that included the current melody note in the top voice, and sort them by various musical criteria to find the most viable options:

voicings =
    Music.Chord.voiceFivePart
        { voiceOne = Music.Range.clarinet
        , voiceTwo = Music.Range.altoSax
        , voiceThree = Music.Range.tenorSax
        , voiceFour = Music.Range.tenorSax
        , voiceFive = Music.Range.baritoneSax
        }
        [ Music.Voicing.FivePart.close ]
        (Music.Chord.majorSix Music.PitchClass.d)
        |> List.filter (Music.Voicing.FivePart.containsPitchInVoiceOne Music.Pitch.d5)

This could save you time, reveal options you might not have considered, and help you focus on your high-level goals.

To my knowledge, elm-music-theory is the first library of its kind to treat the topic of voicing chords in a structured way that reflects an arranger’s process.

I have made every effort to model the concepts I have chosen for this first release as accurately as I could. Because of this design effort, I believe elm-music-theory provides not only a foundation for arranging harmony, but also one that supports many other potential musical applications, such as harmonic analysis, writing counterpoint, and generating music procedurally.

Take a look at the examples that cover analyzing and transposing the chord progression in a song and generating four-part chord voicings.

And if these terms are new to you, here are some learning resources for getting acquainted with the music theory concepts modeled in this library.

What’s next?

Music theory is a large topic, and although I feel elm-music-theory is a solid foundation, it does not provide immediate support for more complex musical use cases.

Here are a few I am working on:

Rhythmic values and time-based structures: Right now this library does not support notes with durations, or structures for organizing them, such as measures, staves, or systems. These features will eventually allow easier generation and manipulation of musical compositions.

Melodic lines and sequences: It is possible to analyze a melodic line and generate variations on it. These variations are known in musical terms as sequences, and they are an important compositional tool for developing a melody. I’m excited for this library to support this in the future, since it has a lot of potential for compositional applications.

Chord progressions with key changes: elm-music-theory already supports Roman numeral analysis of chords in a single key. But with a concept of harmonic movement across key changes, there will be potential to identify more harmonic relationships and to represent more sophisticated harmonic plans, which will be helpful for generating compositions procedurally.

Voicings for polyphonic instruments: This initial release has focused much attention on voicing chords for small groups of monophonic instruments. Chord voicings for polyphonic instruments (like the guitar and the piano) are subject to different principles and constraints, and these will need to be modeled separately for these cases to be well-served by this library.

I hope you enjoy elm-music-theory! Feel free to reach out to me at @duncan on the Elm Slack about your projects and questions.


Originally posted at dmalashock.com

Discussion: How much to pipeline

via Elm - Latest posts by @rupert Rupert Smith on Mon, 28 Sep 2020 10:07:10 GMT

I don’t think it could work because even with pizzas, you still need parenthesis sometimes. For example, I recently wrote a parsing package, and as I cannot export |. and |=, I have to use |> ignore or |> keep, leading to code like this:

PR.succeed identity
    |> PR.ignore PR.spaces
    |> PR.keep (PR.int ExpectingInt InvalidNumber |> PR.map Just)
    |> PR.ignore PR.spaces
    |> PR.ignore (PR.symbol "," ExpectingComma |> PR.optional ())
    |> PR.ignore PR.spaces
    |> PR.forwardOrSkip Nothing [ "," ] ExpectingSpace Discarded

to work around having no parenthesis, I would need to use more let..in blocks:

let 
    parseInt = 
        PR.int ExpectingInt InvalidNumber
            |> PR.map Just

    parseComma = 
        PR.symbol "," ExpectingComma 
            |> PR.optional ()
in
PR.succeed identity
    |> PR.ignore PR.spaces
    |> PR.keep parseInt
    |> PR.ignore PR.spaces
    |> PR.ignore parseComma
    |> PR.ignore PR.spaces
    |> PR.forwardOrSkip Nothing [ "," ] ExpectingSpace Discarded

Maybe that is actually more readable, and perhaps if I was tidying up some code I might even do that. But I could see it being very annoying at the time when you are writing a pipeline, as usually at that point you are just trying to sequence a load of stuff together in order, and don’t want the cognitive interruption of having to create another let..in block (and then delete it again, when you realize you didn’t need it, and then put it back again when you realize you really did…).

I do agree pipelines can be harder to read sometimes, but so handy when you are just trying to figure out something complicated that need to combine sequencing and transformation.

Discussion: How much to pipeline

via Elm - Latest posts by @opvasger Asger Nielsen on Mon, 28 Sep 2020 09:54:48 GMT

To me, choosing between <| and |> is the crux of it all, and not so much whether or not I use them.

favoring <| means that I read function application in the same direction whether I use parenthesis or pipes. This is very important for me, as I won’t have to mentally switch reading-direction when looking at function-applications.

I get that |> feels natural, but I don’t like the trade-off.

Init a task in a module + avoid circular import?

via Elm - Latest posts by @pdamoc Peter Damoc on Mon, 28 Sep 2020 09:51:38 GMT

I guess it should be:

main =
 Browser.element
        { init = \_ -> ( initialModel, initialCmd initialModel)

It is advisable to give functions as little data as possible so. Keep the functions small and with parameters as simple as possible.

So… instead of getTimestamps: Model -> Cmd Msg where you would extract some data from the mode, prefer getTimestamps: Int -> Cmd Msg.

[off my chest] omg elm is so fun

via Elm - Latest posts by @pdamoc Peter Damoc on Mon, 28 Sep 2020 09:17:35 GMT

It’s a sect of the Hindley–Milner church. :angel:

logBase 10 erroneous

via Elm - Latest posts by @mattpiz Matthieu Pizenberg on Mon, 28 Sep 2020 06:24:03 GMT

Float arithmetic is subject to this kind of issues. If I had to count the number of digits of a number, I’d use recursive integer division by 10 such as https://www.geeksforgeeks.org/program-count-digits-integer-3-different-methods/

Call for beta testers of browser extension for better Debug.log output

via Elm - Latest posts by @berend Berend de Boer on Mon, 28 Sep 2020 04:27:13 GMT

This hasn’t been released yet is it? I currently really need something like this!

Init a task in a module + avoid circular import?

via Elm - Latest posts by @Yannick971 Yannick on Mon, 28 Sep 2020 00:01:22 GMT

Alright so I tried and got stuck here:

getTimestamps: Int -> Cmd Msg

in my example the time value is in the Main Model so it would be:
getTimestamps: Model -> Cmd Msg but its the same thing…

The compiler complains because the initialCmd should be of type Cmd and not Model -> Cmd Msg in main:

main =
 Browser.element
        { init = \_ -> ( initialModel, initialCmd )

logBase 10 erroneous

via Elm - Latest posts by @stevensonmt Stevensonmt on Sun, 27 Sep 2020 22:55:48 GMT

I’m using Basics.logBase and am getting a surprising result.
logBase 10 1000 returns 2.9999999999999996. This is problematic for my overall algorithm as I am expecting to be able to use floor to accurately find how many digit “places” I need. Any way I can get logBase 10 1000 to return 3 as expected?

On further investigation, this issue appears to affect every value of 10^x where x%3 == 0.

JSON decode unknown number of fields

via Elm - Latest posts by @system system on Sun, 27 Sep 2020 21:04:40 GMT

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.

Discussion: How much to pipeline

via Elm - Latest posts by @DullBananas on Sun, 27 Sep 2020 20:25:29 GMT

If there were no parenthesis, let statements would be used more. Might be a good thing but things like map3 wouldn’t work well with this

Discussion: How much to pipeline

via Elm - Latest posts by @Chadtech Chadtech on Sun, 27 Sep 2020 20:07:02 GMT

Since pipes and parentheses are substitutes, it seems like teams have to agree on one or the other to avoid having different ways of doing the same thing. And, I think parentheses usually win because everyone is familiar with them, while only a smaller and more hardcore group is addicted to the pizza operators.

So, I have wondered, what would that look like if a team went 100% pizza. And “No parentheses” was their style. What if Elm removed parentheses? Could it work?

 newer latest older