diff --git a/_snippets/aoc_day1.md b/_snippets/aoc_day1.md index c7bc24de..8ddd289e 100644 --- a/_snippets/aoc_day1.md +++ b/_snippets/aoc_day1.md @@ -1,5 +1,5 @@ --- -order: 16 +order: 20 title: AOC_Day1.fs excerpt_separator: code: | @@ -22,7 +22,7 @@ code: | "()(()((()((" |> parseChars |> findEndingFloor 0 |> printf --- -## Solve the Important Problems +## Focus on the Challenges F# excels at solving algorithmic challenges with clarity and precision. The code elegantly tracks an elevator's movement through a building by parsing directional instructions. @@ -31,4 +31,4 @@ F# excels at solving algorithmic challenges with clarity and precision. The code - **Higher-order functions** like `fold` to accumulate state - **Function composition** with the pipeline operator for readable data flow -Notice how the solution reads almost like a plain English description of the problem, making it both maintainable and self-documenting. +Solutions often read almost like a plain English description of the problem, making it both maintainable and self-documenting. diff --git a/_snippets/async_expressions.md b/_snippets/async_expressions.md new file mode 100644 index 00000000..a8ac0565 --- /dev/null +++ b/_snippets/async_expressions.md @@ -0,0 +1,34 @@ +--- +order: 15 +title: AsyncExpressions.fs +excerpt_separator: +code: | + // An async function + let fetchDataAsync url = async { + printfn "Fetching data from %s..." url + do! Async.Sleep 1000 // Simulate network delay + return sprintf "Data from %s" url + } + + // Using pattern matching in async code + let processPersonAsync person = async { + let result = validatePerson person.Age person.Name + match result with + | Ok validated -> + return! fetchDataAsync $"profile/{validated.Name}" + | Error msg -> + return $"Validation error: {msg}" + } + + processPersonAsync { Name = "Snowdrop"; Age = 13} + |> Async.RunSynchronously +--- +## Async Programming made Easy + +F# async expressions provide a powerful way to handle asynchronous programming, making it more readable and maintainable. They allow you to write non-blocking code that looks like synchronous code, which is particularly useful for I/O-bound operations. + +- **Async expressions** provide a clean syntax for defining asynchronous workflows +- **Integration with existing libraries** makes it easy to use async expressions with other F# features +- **Error handling** is simplified with the use of discriminated unions and pattern matching +- **Seamless integration** with F#'s type system ensures type safety and reduces runtime errors +- **Support for cancellation** and timeouts allows you to manage long-running operations effectively \ No newline at end of file diff --git a/_snippets/computation_expressions.md b/_snippets/computation_expressions.md index fb646789..0debb26f 100644 --- a/_snippets/computation_expressions.md +++ b/_snippets/computation_expressions.md @@ -3,29 +3,7 @@ order: 17 title: ComputationExpressions.fs excerpt_separator: code: | - // Sequence generation - let rec fizzBuzzSeq n = - seq { - yield - match n with - | x when x % 15 = 0 -> "fizzbuzz" - | x when x % 3 = 0 -> "fizz" - | x when x % 5 = 0 -> "buzz" - | _ -> n.ToString() - - yield! fizzBuzzSeq (n + 1) - } - - fizzBuzzSeq 1 |> Seq.take 100 |> Seq.iter (printfn "%s") - - // Asynchronous programming with computation expressions - let fetchDataAsync url = async { - printfn "Fetching data from %s..." url - do! Async.Sleep 1000 // Simulate network delay - return sprintf "Data from %s" url - } - - // Custom computation expression for validation + // Define a custom computation expression for validation type ValidationBuilder() = member _.Bind(x, f) = match x with @@ -38,7 +16,7 @@ code: | type Person = { Name: string; Age: int } - // Using our custom computation expression + // Use the custom computation expression let validatePerson age name = validate { let! validAge = if age >= 0 && age < 150 then Ok age @@ -50,23 +28,10 @@ code: | return { Name = validName; Age = validAge } } - - // Using multiple computation expressions together - let processPersonAsync person = async { - let result = validatePerson person.Age person.Name - match result with - | Ok validated -> - return! fetchDataAsync $"profile/{validated.Name}" - | Error msg -> - return $"Validation error: {msg}" - } - - processPersonAsync { Name = "Snowdrop"; Age = 13} - |> Async.RunSynchronously --- -## Expressive Control Flow with Computation Expressions +## Control the Complexity with Computation Expressions -F# computation expressions provide an elegant syntax for complex control flows with a clean, readable notation that some say is F#'s superpower. +F# computation expressions give you an elegant syntax for compositional control flows with a clean, readable notation that some say is F#'s superpower. - **Simplified asynchronous code** makes non-blocking operations read like synchronous code - **Custom control flow abstractions** create domain-specific mini-languages diff --git a/_snippets/domain_modelling.md b/_snippets/domain_modelling.md index e4b42844..d88f1ffb 100644 --- a/_snippets/domain_modelling.md +++ b/_snippets/domain_modelling.md @@ -1,9 +1,11 @@ --- -order: 15 +order: 11 title: PaymentSystem.fs code: | type CardInfo = { Number: string; Expiry: string; Cvv: string } + type BankInfo = { AccountNumber: string; RoutingNumber: string } + type PayPalInfo = { Email: string; Token: string } type PaymentMethod = @@ -34,8 +36,8 @@ code: | payment.Amount pp.Email --- -## Making Invalid States Unrepresentable -This example showcases F#'s ability to create precise domain models that prevent errors at compile time. +## Domain Models made Simple and Safe +F# gives you superb capabilities to create precise domain models that prevent errors at compile time. - **Discriminated unions** model each payment method with exactly the fields it needs - **No "impossible" states** can exist - a credit card payment can't have a routing number diff --git a/_snippets/fable.md b/_snippets/fable.md index 50e827b9..c141e0a9 100644 --- a/_snippets/fable.md +++ b/_snippets/fable.md @@ -30,9 +30,9 @@ code: | ] ) --- -## F# for JavaScript Development +## F# for JavaScript and the Full Stack -F# isn't just for .NET development - with [F# web technologies]({{ '/use/web-apps/' | relative_url }}), you can target JavaScript environments directly. +F# is for both client and server. With [F# web technologies]({{ '/use/web-apps/' | relative_url }}), you can target JavaScript environments directly. This means you can use F# to build web applications, mobile apps, and even serverless functions that run in the cloud. - **Type-safe DOM manipulation** catches errors at compile time, not runtime - **Seamless React integration** with hooks and modern patterns diff --git a/_snippets/helloworld.md b/_snippets/helloworld.md index c4efa735..4b20d575 100644 --- a/_snippets/helloworld.md +++ b/_snippets/helloworld.md @@ -9,23 +9,20 @@ code: | let greets = [ "World" "Solar System" - "Milky Way Galaxy" - "Local Galactic Group" - "Virgo Supercluster" + "Galaxy" "Universe" "Omniverse" ] greets |> List.iter hello --- -## Concise and Expressive like Python +## Concise like Python -This simple "Hello World" example demonstrates F#'s elegant syntax and functional approach to programming. +F#'s elegant syntax and strong typing give you the tools to solve problems succinctly, robustly and happily. -- **Concise function syntax** defines reusable functions with minimal boilerplate -- **Clean list creation** uses indentation-based syntax without requiring commas +- **Concise syntax** defines reusable functions with minimal boilerplate +- **Simple lists** uses indentation-based syntax without requiring commas - **String interpolation** provides readable string formatting with the `$` prefix - **Pipeline operator** creates a readable left-to-right flow of data -- **Higher-order functions** allow applying operations across collections easily In just a few lines of code, F# provides a clean, readable implementation that would require significantly more boilerplate in many other languages. This expressive style becomes even more valuable as your programs grow in complexity. \ No newline at end of file diff --git a/_snippets/oop.md b/_snippets/oop.md index 1bb92d78..28ed4ca2 100644 --- a/_snippets/oop.md +++ b/_snippets/oop.md @@ -1,5 +1,5 @@ --- -order: 11 +order: 10 title: OOP.fs excerpt_separator: code: | @@ -10,52 +10,35 @@ code: | // Class implementation with interface type Calculator(precision: int) = - // Private field using let binding - let mutable _precision = precision // Interface implementation interface ICalculator with - member this.Add x y = x + y - member this.Multiply x y = x * y + member _.Add x y = x + y + member _.Multiply x y = x * y // Public methods - member this.Subtract(x, y) = x - y - - // Property with explicit getter/setter - member this.Precision - with get() = _precision - and set(value) = _precision <- value + member _.Subtract(x, y) = x - y // Method using property - member this.RoundToPrecision(value: float) = - System.Math.Round(value, this.Precision) + member _.RoundToPrecision(value: float) = + System.Math.Round(value, precision) // Method with default parameter - member this.Power(x: float, ?exponent: float) = + member _.Power(x: float, ?exponent: float) = let exp = defaultArg exponent 2.0 System.Math.Pow(x, exp) + // Object expression (anonymous implementation) + let quickCalc = + { new ICalculator with + member _.Add x y = x + y + member _.Multiply x y = x * y } + // Type extension - add method to existing type type System.Int32 with - member this.IsEven = this % 2 = 0 - - // Demo usage - let demo() = - // Object expression (anonymous implementation) - let quickCalc = - { new ICalculator with - member _.Add x y = x + y - member _.Multiply x y = x * y } - - // Class instantiation - let calc = Calculator(2) - - printfn "5 - 3 = %d" (calc.Subtract(5, 3)) - printfn "Is 10 even? %b" (10.IsEven) - printfn "2.345 rounded = %f" (calc.RoundToPrecision(2.345)) - printfn "2^3 = %f" (calc.Power(2.0, 3.0)) + member x.IsEven = x % 2 = 0 --- -## Object Programming Made Simple +## Objects Made Simple F# is **functional first** and **immutable by default**, but it also provides pragmatic support for object programming. diff --git a/_snippets/sequence_expressions.md b/_snippets/sequence_expressions.md new file mode 100644 index 00000000..5d855f31 --- /dev/null +++ b/_snippets/sequence_expressions.md @@ -0,0 +1,30 @@ +--- +order: 16 +title: SequenceExpressions.fs +excerpt_separator: +code: | + // A function generating a sequence of numbers + let rec fizzBuzzSeq n = seq { + yield + match n with + | x when x % 15 = 0 -> "fizzbuzz" + | x when x % 3 = 0 -> "fizz" + | x when x % 5 = 0 -> "buzz" + | _ -> n.ToString() + + yield! fizzBuzzSeq (n + 1) + } + + // Process the sequence using a pipeline + fizzBuzzSeq 1 + |> Seq.take 100 + |> Seq.iter (printfn "%s") +--- +## Data Pipelines with Sequence Expressions + +F# sequence expressions provide compositional, functional stream processing capabilities that integrate seamlessly with every part of the language. + +- **Simplified data generation** through sequence expressions +- **Compositional data processing** through library routines +- **On-demand evaluation** of data streams +- **Fluent, maintainable code** that is easy to read and understand diff --git a/_snippets/typeproviders.md b/_snippets/typeproviders.md index ec3e0c11..b48e2674 100644 --- a/_snippets/typeproviders.md +++ b/_snippets/typeproviders.md @@ -8,15 +8,15 @@ code: | type PeopleDB = CsvProvider<"people.csv"> let printPeople () = - let people = PeopleDB.Load("people.csv") // this can be a URL + let people = PeopleDB.Load("people.csv") for person in people.Rows do - // access the csv fields with intellisense and type safety! + // Access the CSV fields with intellisense and type safety! printfn $"Name: %s{person.Name}, Id: %i{person.Id}" --- -## Type-Safe Access to External Data +## Type-Safe, Integrated Data -F# Type Providers create a seamless bridge between your code and external data sources. +F# Type Providers create a seamless bridge between your code and data sources. - **Zero-friction data access** connects to CSV, JSON, XML, SQL, and more without manual mapping - **Static typing at compile time** prevents runtime errors when accessing external data diff --git a/_snippets/unitsOfMeasure.md b/_snippets/unitsOfMeasure.md index 34af7c04..aaada29a 100644 --- a/_snippets/unitsOfMeasure.md +++ b/_snippets/unitsOfMeasure.md @@ -1,10 +1,9 @@ --- -order: 1 +order: 22 title: UnitsOfMeasure.fs excerpt_separator: code: | - [] type m // Meters - [] type s // Seconds + open FSharp.Data.UnitSystems.SI // Acceleration due to gravity let g = 9.81 @@ -17,9 +16,9 @@ code: | let fallDistance = distance fallDuration printfn $"Distance fallen in {fallDuration}s is {fallDistance}m" --- -## Units of Measure +## Numaric Safety through Units of Measure -F# offers compile-time unit safety without runtime overhead, enforcing correctness mathematically. +F# offers world-class compile-time unit safety without runtime overhead, giving you the power to express your domain in a type-safe way. This is particularly useful in scientific, engineering and financial applications where unit errors can lead to catastrophic results. - **Compile-time dimensional safety** catches errors before running, preventing scientific and engineering mistakes - **Domain-specific units** express quantities that directly reflect your problem space