рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рд╡рд╣ рдирд╣реАрдВ рд╣реИ рдЬреЛ рд╣рдореЗрдВ рдмрддрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ

рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдПрдХ рдмрд╣реБрдд рд╣реА рдЕрдЬреАрдм рдкреНрд░рддрд┐рдорд╛рди рд╣реИред рдПрдХ рддрд░рдл, рд╣рд░ рдХреЛрдИ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирддрд╛ рд╣реИ, рдФрд░ рд╣рд░ рдХреЛрдИ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрдЯрд░реНрди рдорд┐рд▓рд╛рди рдФрд░ рд▓рдВрдмреЛрджрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реИ, рджреВрд╕рд░реА рддрд░рдл, рдХреБрдЫ рд▓реЛрдЧ рдЖрдорддреМрд░ рдкрд░ рд╢реБрджреНрдз рдПрдлрдкреА рднрд╛рд╖рд╛ рдореЗрдВ рд▓рд┐рдЦрддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдпрд╣ рд╕рдордЭ рдХрд┐ рдпрд╣ рдорд┐рдердХреЛрдВ рдФрд░ рд╢рд╣рд░реА рдХрд┐рдВрд╡рджрдВрддрд┐рдпреЛрдВ рдореЗрдВ рд╡рд╛рдкрд╕ рдЬрд╛рдиреЗ рдХреА рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ, рдЬреЛ рд╕рдЪреНрдЪрд╛рдИ рд╕реЗ рдмрд╣реБрдд рджреВрд░ рд╣реИрдВ, рдФрд░ рд▓реЛрдЧреЛрдВ рдХреЛ рдпрд╣ рдзрд╛рд░рдгрд╛ рд╣реИ рдХрд┐ "рдПрдлрдкреА рдЬреАрд╡рди рд╕реЗ рдкреГрдердХ рд╕рднреА рднрдЧреНрди рдЧрдгрдирд╛ рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд╣реИ, рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд┐рджреНрдз рд░рд┐рдХреЙрд░реНрдб рд╣реИред рд▓рдбрд╝рд╛рдИ рдХреЗ рд╕рдордп рдореЗрдВ рдкрд░реАрдХреНрд╖рдг OOPред "



рдпрджреНрдпрдкрд┐ рд▓реЛрдЧ рдЖрдорддреМрд░ рдкрд░ рдПрдлрдкреА рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреА рд╕реБрд╡рд┐рдзрд╛ рдХреЛ рдкрд╣рдЪрд╛рдирддреЗ рд╣реИрдВ, рдпрд╣ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реИ:


int Factorial(int n)
{
    Log.Info($"Computing factorial of {n}");
    return Enumerable.Range(1, n).Aggregate((x, y) => x * y);
}


int Factorial(int n)
{
    int result = 1;
    for (int i = 2; i <= n; i++)
    {
        result *= i;
    }
    return result;
}

? . .


, ? , , тАФ ? , , .


, ? , , . :


тАФ , .

, , ? тАФ , . , :


f f(x) x

, " ". тАФ , ? ? " " ? , , , .


? :


тАФ ,

- var x = foo() var x = result_of_foo . . ( ) . тАФ , " ". , . , CPU тАФ ( , ). тАФ !


. , ? , , - Factorial(5) 120 тАФ ( " , " , . , , , ).


? : .


, , var x = result_of_foo var x = foo() . "Equational reasoning", " ". , тАФ , .


: . , . ST, . тАФ : ST . , , , тАФ .



тАФ . ? , ST ( ) , тАж тАФ . goto , , goto , - .


Equational reasoning , : . , , , .


. C#, , ( )


var something = function();
DoStuff(this.Field, something);

, :


DoStuff(this.Field, function());

, , . , function :


... - 
this.Field = GetUpdatedVersion(this.Field, localData) // ! 
...     

:


var something = function();
var arg1 = this.Field;      //   function -  !
var arg2 = something;
DoStuff(arg1, arg2);

:


var arg1 = this.Field;      //   function -   !
var arg2 = function();
DoStuff(arg1, arg2);

DoStuff , .


? " , "? , , . .


, , . , , - C# , , DI , function DoStuff, . , , .


. , . , - . , . , , . , . , , , . , тАФ . тАФ , - .



, Scala ( , , c ). , C#.


, . , .



, , :


public class Cafe
{
    public Coffee BuyCoffee(CreditCard card)
    {
        var cup = new Coffee()
        card.Charge(cup.Price)
        return cup
    }
}

card.Charge(cup.Price) . тАФ , - - -, . , Coffee, "" " ".


- . " !". , :


public class Cafe
{
    public Coffee BuyCoffee(CreditCard card, IPaymentProvider paymentProvider)
    {
        var cup = new Coffee()
        paymentProvider.Charge(card, cup.Price)
        return cup
    }
}

: IPaymentProvider. .


  • - IPaymentProvider, .
  • - . тАФ InMemory DB, Insert/Save/тАж , ( ) , . , тАФ ? , - , , .
  • - . N . ( ):

public class Cafe
{
    public Coffee BuyCoffee(CreditCard card, IPaymentProvider paymentProvider)
    {
        var cup = new Coffee()
        paymentProvider.Charge(card, cup.Price)
        return cup
    }

    public Coffee[] BuyCoffees(int count, CreditCard card, IPaymentProvider paymentProvider)
    {
        //      0   , 
        //       0 
        if (count == 0) return Array.Empty<Coffee>(); 
        var cups = Enumerable.Range(0, count).Select(_ => new Coffee()).ToArray();
        paymentProvider.Charge(card, cups[0].Price * count)
        return cups
    }
}

. - , .



, ? тАФ , , . :


public class Cafe
{
    public (Coffee, Charge) BuyCoffee(CreditCard card)
    {
        var cup = new Coffee()
        return (cup, new Charge(card, cup.Price))
    }
}

, . , , . , Charge . : . Charge DTO . , . , . , . , !


N ? , N BuyCoffee , .


public class Cafe
{
    public (Coffee, Charge) BuyCoffee(CreditCard card)
    {
        var cup = new Coffee()
        return (cup, new Charge(card, cup.Price))
    }

    public (Coffee[], Charge) BuyCoffees(int count, CreditCard card)
    {
        var (coffees, charges) = Enumerable.Range(0, count)
                                           .Select(_ => BuyCoffee(card))
                                           .Unzip();
        return (coffees, charges.Aggregate((c1, c2) => c1.ombine(c2))
    }
}

- Combine:


public class Charge
{
    public CreditCard Card { get; set; }
    public double Amount { get; set; }

    public Charge(CreditCard card, double amount)
    {
        Card = card;
        Amount = amount;
    }

    public Charge Combine(Charge other)
    {
        if (Card != other.Card) 
            throw new ArgumentException("Can't combine charges to different cards");
        return new Charge(Card, Amount + other.Amount);
    }
}

- . , , :


IEnumerable<Charge> Coalesce(IEnumerable<Charge> charges) => 
    charges.GroupBy(x => x.Card).Select(g => g.Aggregate((c1, c2) => c1.Combine(c2))

, . , , , .


, , - , , , - Cafe. , , , , , - ( , ).


, IPaymentProvider , , : , , , "" , , . , , .


, , . " " , . RAII: , .


?


тАФ , . , , . , , , . ( int ) , (, goto) , (Templates vs Generics) , .


, , . , "" , , , . ? void UpdateOrders() void UpdateUsers() () -> (), . () -> OrdersUpdate () -> UsersUpdate. , ( ) , .


? , ( Rust)


//   ,  - ,      
fn foo<T>(a: &[T], b: T) -> T { ...- ... }

, , , тАФ b . ? , T. . , тАФ .



let a = [1,2,3,4,5];
let b = foo(a, 10);
assert!(b == 10 || a.iter().any(|x| x == b))

, UB - ( ). , , - - , (, , ).


:


fn foo<T>(a: &[T]) -> T { ...- ... }

, , , - . , , Bottom- тКе. ? T, . a. -, . .


, , .


, ? , . , :


T Foo<T>(List<T> list, T value) => default(T);

, . . , , тАФ . , , , .


, T? :


fn foo<T: Default>(a: &[T]) -> T { ...- ... }

, , . , , - . тАФ . . ! , default(T).


99% , . , . Haskell Hoogle . .


(a -> Bool) -> [a] -> [a] (, : , ) filter takeWhile.


. , ? , .


fn bar<T>(s: String) -> T { ... } // -
bar :: String -> a                // -

, , . , тАФ . , тКе. , . , , :


fn bar<T>(s: String) -> T { 
    panic!(s);
}

тАФ ( ), . , . , , , .


, , , . foo 1000 , , . . 1000 . .


- ?


, . "", , " , HTTP , . . ".


, , . ", . , ( )? , , !".


? IO, . , Charge , /. IO , print "Hello world" . main = print "Hello world" . ?


, IO. main. , . "" тАФ , , , . .


, , . main , .


, , тАФ , . , . "", . .


, , . Rust:


fn main() {
    let _ = print!("Hello ");
    println!("world!");
}

"Hello world!". Haskell:


main :: IO ()
main = do
  let _ = print "Hello "
  print "world!"

"world!". . " Hello", . . main world!, . Rust print! , - .


( , - ) , . " " . , " ( ), HTTP ( , ), . , .



, . , , . , . - ANSI C , . . , Scala Haskell тАФ . , , , , . , .


. , - . DI. " "/" "/"...", .


, , , . . "" , , . , тАФ .

Source: https://habr.com/ru/post/hi479238/


All Articles