diff --git a/.gitignore b/.gitignore index 20384474..85a6d1b4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,10 @@ _site .sass-cache .jekyll-metadata -Gemfile.lock \ No newline at end of file +Gemfile.lock + +.jekyll-cache + +.idea +*.iml +/draft/ diff --git a/CNAME b/CNAME new file mode 100644 index 00000000..a5a90e95 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +www.writeonly.pl diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 89828dec..00000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 twocolumn - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md deleted file mode 100644 index 0a8da578..00000000 --- a/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Minimal Mistakes remote theme starter - -Fork this repo for the quickest method of getting started with the [Minimal Mistakes Jekyll theme](https://github.com/mmistakes/minimal-mistakes). - -Contains basic configuration to get you a site with: - -- Sample posts. -- Sample top navigation. -- Sample author sidebar with social links. -- Sample footer links. -- Paginated home page. -- Archive pages for posts grouped by year, category, and tag. -- Sample about page. -- Sample 404 page. -- Site wide search. - -Replace sample content with your own and [configure as necessary](https://mmistakes.github.io/minimal-mistakes/docs/configuration/). - ---- - -## Troubleshooting - -If you have a question about using Jekyll, start a discussion on the [Jekyll Forum](https://talk.jekyllrb.com/) or [StackOverflow](https://stackoverflow.com/questions/tagged/jekyll). Other resources: - -- [Ruby 101](https://jekyllrb.com/docs/ruby-101/) -- [Setting up a Jekyll site with GitHub Pages](https://jekyllrb.com/docs/github-pages/) -- [Configuring GitHub Metadata](https://github.com/jekyll/github-metadata/blob/master/docs/configuration.md#configuration) to work properly when developing locally and avoid `No GitHub API authentication could be found. Some fields may be missing or have incorrect data.` warnings. diff --git a/_collections/_books/bdd-w-dzialaniu.html b/_collections/_books/bdd-w-dzialaniu.html new file mode 100644 index 00000000..fff4ba13 --- /dev/null +++ b/_collections/_books/bdd-w-dzialaniu.html @@ -0,0 +1,10 @@ +--- +title-shortcut: 'BDD w działaniu' +title: 'BDD w działaniu. Sterowanie zachowaniem w rozwoju aplikacji' +title-of-original: "BDD in Action: Behavior-Driven Development for the whole software lifecycle" +year-of-publishment: 2015 +authors: + - 'John Ferguson Smart' +langs: java +tags: bdd +--- diff --git a/_collections/_books/bootstrap-4-dla-zaawansowanych.html b/_collections/_books/bootstrap-4-dla-zaawansowanych.html new file mode 100644 index 00000000..6aca159a --- /dev/null +++ b/_collections/_books/bootstrap-4-dla-zaawansowanych.html @@ -0,0 +1,10 @@ +--- +title-shortcut: 'Bootstrap 4 dla zaawansowanych' +title: 'Bootstrap 4 dla zaawansowanych. Jak pisać znakomite aplikacje internetowe. Wydanie II' +title-of-original: "Mastering Bootstrap 4 – Second Edition" +year-of-publishment: 2018 +authors: + - 'Benjamin Jakobus' + - 'Jason Marah' +libs: bootstrap +--- diff --git a/_collections/_books/bootstrap-tworzenie-interfejsow-stron-www.html b/_collections/_books/bootstrap-tworzenie-interfejsow-stron-www.html new file mode 100644 index 00000000..58a340c0 --- /dev/null +++ b/_collections/_books/bootstrap-tworzenie-interfejsow-stron-www.html @@ -0,0 +1,9 @@ +--- +title-shortcut: 'Bootstrap. Tworzenie interfejsow stron www' +title: 'Bootstrap. Tworzenie interfejsow stron www. Technologia na start' +title-of-original: "Jump Start Bootstrap" +year-of-publishment: 2014 +authors: + - 'Syed Fazle Rahman' +libs: bootstrap +--- diff --git a/_collections/_books/bootstrap-tworzenie-wlasnych-stylow-graficznych.html b/_collections/_books/bootstrap-tworzenie-wlasnych-stylow-graficznych.html new file mode 100644 index 00000000..065b19bc --- /dev/null +++ b/_collections/_books/bootstrap-tworzenie-wlasnych-stylow-graficznych.html @@ -0,0 +1,9 @@ +--- +title-shortcut: 'Bootstrap. Tworzenie własnych stylów graficznych' +title: 'Bootstrap. Tworzenie własnych stylów graficznych' +title-of-original: "Bootstrap. Tworzenie własnych stylów graficznych" +year-of-publishment: 2017 +authors: + - 'Radosław Gryczan' +libs: bootstrap +--- diff --git a/_collections/_books/czysta-architektura.html b/_collections/_books/czysta-architektura.html new file mode 100644 index 00000000..eb61aa9f --- /dev/null +++ b/_collections/_books/czysta-architektura.html @@ -0,0 +1,8 @@ +--- +title-shortcut: 'Czysta Architektura' +title: 'Czysta architektura. Struktura i design oprogramowania. Przewodnik dla profesjonalistów' +title-of-original: "Clean Architecture: A Craftsman's Guide to SoftwareStructure and Design (Robert C. Martin Series)" +year-of-publishment: 2018 +authors: + - 'Robert C. Martin' +--- diff --git a/_collections/_books/czysty-kod.html b/_collections/_books/czysty-kod.html new file mode 100644 index 00000000..28f64cd4 --- /dev/null +++ b/_collections/_books/czysty-kod.html @@ -0,0 +1,8 @@ +--- +title-shortcut: 'Czysty kod' +title: 'Czysty kod. Podręcznik dobrego programisty' +title-of-original: "Clean Code: A Handbook of Agile Software Craftsmanship" +year-of-publishment: 2009 +authors: + - 'Robert C. Martin' +--- diff --git a/_collections/_books/ddd-dla-architektow-oprogramowania.html b/_collections/_books/ddd-dla-architektow-oprogramowania.html new file mode 100644 index 00000000..b6f92944 --- /dev/null +++ b/_collections/_books/ddd-dla-architektow-oprogramowania.html @@ -0,0 +1,9 @@ +--- +title-shortcut: 'DDD dla architektów oprogramowania' +title: 'DDD dla architektów oprogramowania' +title-of-original: "Implementing Domain-Driven Design" +year-of-publishment: 2013 +authors: + - 'Vaughn Vernon' +tags: ddd +--- diff --git a/_collections/_books/ddd.html b/_collections/_books/ddd.html new file mode 100644 index 00000000..017edc92 --- /dev/null +++ b/_collections/_books/ddd.html @@ -0,0 +1,9 @@ +--- +title-shortcut: 'DDD' +title: 'DDD. Kompendium wiedzy' +title-of-original: "Domain-Driven Design Distilled" +year-of-publishment: 2016 +authors: + - 'Vaughn Vernon' +tags: ddd +--- diff --git a/_collections/_books/docker-dla-praktykow.html b/_collections/_books/docker-dla-praktykow.html new file mode 100644 index 00000000..0d8b3ab3 --- /dev/null +++ b/_collections/_books/docker-dla-praktykow.html @@ -0,0 +1,11 @@ +--- +title-shortcut: 'Docker dla praktyków' +title: 'Docker dla praktyków. Wydanie II' +title-of-original: "Learning Docker - Second Edition" +year-of-publishment: 2017 +authors: +- 'Jeeva S. Chelladhurai' +- 'Vinod Singh' +- 'Pethuru Raj' +tags: docker +--- diff --git a/_collections/_books/docker-programowanie-aplikacji-dla-zaawansowanych.html b/_collections/_books/docker-programowanie-aplikacji-dla-zaawansowanych.html new file mode 100644 index 00000000..7f059fc5 --- /dev/null +++ b/_collections/_books/docker-programowanie-aplikacji-dla-zaawansowanych.html @@ -0,0 +1,10 @@ +--- +title-shortcut: 'Docker. Programowanie aplikacji dla zaawansowanych' +title: 'Docker. Programowanie aplikacji dla zaawansowanych. Wydanie II' +title-of-original: "Mastering Docker - Second Edition" +year-of-publishment: 2017 +authors: +- 'Russ McKendrick' +- 'Scott Gallagher' +tags: docker +--- diff --git a/_collections/_books/domain-driven-design.html b/_collections/_books/domain-driven-design.html new file mode 100644 index 00000000..e0cf6519 --- /dev/null +++ b/_collections/_books/domain-driven-design.html @@ -0,0 +1,9 @@ +--- +title-shortcut: 'Domain-Driven Design' +title: 'Domain-Driven Design. Zapanuj nad złożonym systemem informatycznym' +title-of-original: "Domain-Driven Design: Tackling Complexity in the Heart of Software" +year-of-publishment: 2004 +authors: + - 'Eric Evans' +tags: ddd +--- diff --git a/_collections/_books/f-4-0-dla-zaawansowanych.html b/_collections/_books/f-4-0-dla-zaawansowanych.html new file mode 100644 index 00000000..02932796 --- /dev/null +++ b/_collections/_books/f-4-0-dla-zaawansowanych.html @@ -0,0 +1,11 @@ +--- +title-shortcut: 'F# 4.0 dla zaawansowanych' +title: 'F# 4.0 dla zaawansowanych. Wydanie IV' +title-of-original: "Expert F# 4.0, 4th Edition" +year-of-publishment: 2015 +authors: + - 'Don Syme' + - 'Adam Granicz' + - 'Antonio Cisternino' +langs: fsharp +--- diff --git a/_collections/_books/fpmortals.html b/_collections/_books/fpmortals.html new file mode 100644 index 00000000..2c4ad5e7 --- /dev/null +++ b/_collections/_books/fpmortals.html @@ -0,0 +1,12 @@ +--- +title-shortcut: 'FP dla dla Śmiertelników' +title: 'Programowanie Funkcyjne dla Śmiertelników ze Scalaz' +title-of-original: "Functional Programming for Mortals with Scalaz" +year-of-publishment: 2019 +authors: + - 'Sam Halliday' + - 'Wojciech Pituła' +langs: haskell scala +libs: scalaz +--- +Programowanie Funkcyjne dla Śmiertelników ze Scalaz \ No newline at end of file diff --git a/_collections/_books/google-app-engine.html b/_collections/_books/google-app-engine.html new file mode 100644 index 00000000..fa475638 --- /dev/null +++ b/_collections/_books/google-app-engine.html @@ -0,0 +1,10 @@ +--- +title-shortcut: 'Google App Engine' +title: 'Google App Engine. Kod w chmurze' +title-of-original: "Code in the Could" +year-of-publishment: 2011 +authors: + - 'Mark C. Chu-Carroll' +langs: java python +libs: gwt +--- diff --git a/_collections/_books/hibernate-search.html b/_collections/_books/hibernate-search.html new file mode 100644 index 00000000..2126b846 --- /dev/null +++ b/_collections/_books/hibernate-search.html @@ -0,0 +1,10 @@ +--- +title-shortcut: 'Hibernate Search' +title: 'Hibernate Search. Skuteczne wyszukiwanie' +title-of-original: "Hibernate Search by Example" +year-of-publishment: 2013 +authors: + - 'Steve Perkins' +langs: java +libs: hibernate +--- diff --git a/_collections/_books/java-programowanie-funkcyjne.html b/_collections/_books/java-programowanie-funkcyjne.html new file mode 100644 index 00000000..e023f978 --- /dev/null +++ b/_collections/_books/java-programowanie-funkcyjne.html @@ -0,0 +1,9 @@ +--- +title-shortcut: 'Java. Programowanie funkcyjne' +title: 'Java. Programowanie funkcyjne' +title-of-original: "Functional Programming in Java: How to improve your Java programs using functional techniques" +year-of-publishment: 2018 +authors: + - 'Pierre-Yves Saumont' +langs: java +--- diff --git a/_collections/_books/jquery.html b/_collections/_books/jquery.html new file mode 100644 index 00000000..d87de0be --- /dev/null +++ b/_collections/_books/jquery.html @@ -0,0 +1,10 @@ +--- +title-shortcut: 'jQuery' +title: 'jQuery. Kod doskonały' +title-of-original: "jQuery. Kod doskonały" +year-of-publishment: 2012 +authors: + - 'Peweł Mikołajewski' +langs: javascript +libs: jquery +--- diff --git a/_collections/_books/junit.html b/_collections/_books/junit.html new file mode 100644 index 00000000..80852230 --- /dev/null +++ b/_collections/_books/junit.html @@ -0,0 +1,10 @@ +--- +title-shortcut: 'JUnit' +title: 'Testowanie aplikacji Java za pomocą JUnit' +title-of-original: "Testowanie aplikacji Java za pomocą JUnit" +year-of-publishment: 2018 +authors: + - 'Radosław Sokół' +langs: java +libs: junit +--- diff --git a/_collections/_books/kotlin-w-akcji.html b/_collections/_books/kotlin-w-akcji.html new file mode 100644 index 00000000..baaf8b5e --- /dev/null +++ b/_collections/_books/kotlin-w-akcji.html @@ -0,0 +1,10 @@ +--- +title-shortcut: 'Kotlin w akcji' +title: 'Kotlin w akcji' +title-of-original: "Kotlin in Action" +year-of-publishment: 2017 +authors: + - 'Dmitry Jemerov' + - 'Svetlana Isakova' +langs: kotlin +--- diff --git a/_collections/_books/legendarny-osobomiesiac-opowiesci-o-inzynierii-oprogramowania-wydanie-ii.html b/_collections/_books/legendarny-osobomiesiac-opowiesci-o-inzynierii-oprogramowania-wydanie-ii.html new file mode 100644 index 00000000..597ffbbd --- /dev/null +++ b/_collections/_books/legendarny-osobomiesiac-opowiesci-o-inzynierii-oprogramowania-wydanie-ii.html @@ -0,0 +1,15 @@ +--- +title-shortcut: 'Legendarny osobomiesiąc' +title: 'Legendarny osobomiesiąc. Opowieści o inżynierii oprogramowania. Wydanie II' +title-of-original: "The Mythical Man-Month: Essays on Software Engineering, Anniversary Edition (2nd Edition)" +year-of-publishment: 1995 +authors: + - 'Frederick P. Brooks Jr.' +--- + + + + + + + diff --git a/_collections/_books/mistrz-czystego-kodu.html b/_collections/_books/mistrz-czystego-kodu.html new file mode 100644 index 00000000..8d56fbc2 --- /dev/null +++ b/_collections/_books/mistrz-czystego-kodu.html @@ -0,0 +1,8 @@ +--- +title-shortcut: 'Mistrz czystego kodu' +title: 'Mistrz czystego kodu. Kodeks postępowania profesjonalnych programistów' +title-of-original: "The Clean Coder: A Code of Conduct for Professional Programmers" +year-of-publishment: 2011 +authors: + - 'Robert C. Martin' +--- diff --git a/_collections/_books/nosql-newsql-bigdata.html b/_collections/_books/nosql-newsql-bigdata.html new file mode 100644 index 00000000..326cb7f0 --- /dev/null +++ b/_collections/_books/nosql-newsql-bigdata.html @@ -0,0 +1,8 @@ +--- +title-shortcut: 'NoSQL, NewSQL i BigData' +title: 'NoSQL, NewSQL i BigData. Bazy danych następnej generacji' +title-of-original: "Next Generation Databases: NoSQL and Big Data" +year-of-publishment: 2015 +authors: + - 'Guy Harrison' +--- diff --git a/_collections/_books/pragmatyczny-programista.html b/_collections/_books/pragmatyczny-programista.html new file mode 100644 index 00000000..bb8b053d --- /dev/null +++ b/_collections/_books/pragmatyczny-programista.html @@ -0,0 +1,9 @@ +--- +title-shortcut: 'Pragmatyczny programista' +title: 'Pragmatyczny programista. Od czeladnika do mistrza' +title-of-original: 'The Pragmatic Programmer. From Journeyman to Master' +year-of-publishment: 2010 +authors: + - 'Andrew Hunt' + - 'David Thomas' +--- diff --git a/_collections/_books/programowanie-funkcyjne-krok-po-kroku.html b/_collections/_books/programowanie-funkcyjne-krok-po-kroku.html new file mode 100644 index 00000000..f5b0f680 --- /dev/null +++ b/_collections/_books/programowanie-funkcyjne-krok-po-kroku.html @@ -0,0 +1,9 @@ +--- +title-shortcut: 'Programowanie funkcyjne. Krok po kroku' +title: 'Programowanie funkcyjne. Krok po kroku' +title-of-original: "Becoming Functional" +year-of-publishment: 2014 +authors: + - 'Joshua Backfield' +langs: java scala +--- diff --git a/_collections/_books/programowanie-funkcyjne.html b/_collections/_books/programowanie-funkcyjne.html new file mode 100644 index 00000000..548ee09c --- /dev/null +++ b/_collections/_books/programowanie-funkcyjne.html @@ -0,0 +1,9 @@ +--- +title-shortcut: 'Programowanie funkcyjne' +title: 'Programowanie funkcyjne. Poznaj Clojure Elixir Haskell Scala Swift' +title-of-original: "Functional Programming: A PragPub Anthology: Exploring Clojure, Elixir, Haskell, Scala, and Swift" +year-of-publishment: 2014 +authors: + - 'Swaine Michael' +langs: clojure elixir haskell scala swift +--- diff --git a/_collections/_books/programowanie-w-jezyku-clojure.html b/_collections/_books/programowanie-w-jezyku-clojure.html new file mode 100644 index 00000000..59bc86e0 --- /dev/null +++ b/_collections/_books/programowanie-w-jezyku-clojure.html @@ -0,0 +1,10 @@ +--- +title-shortcut: 'Programowanie w języku Clojure' +title: 'Programowanie w języku Clojure' +title-of-original: "Programming Clojure" +year-of-publishment: 2012 +authors: + - 'Stuart Halloway' + - 'Aaron Bedra' +langs: clojure +--- diff --git a/_collections/_books/programowanie-w-jezyku-rust.html b/_collections/_books/programowanie-w-jezyku-rust.html new file mode 100644 index 00000000..2abfe99a --- /dev/null +++ b/_collections/_books/programowanie-w-jezyku-rust.html @@ -0,0 +1,10 @@ +--- +title-shortcut: 'Programowanie w języku Rust' +title: 'Programowanie w języku Rust' +title-of-original: "The Rust Programming Language" +year-of-publishment: 2019 +authors: + - 'Klabnik Steve' + - 'Nichols Carol' +langs: rust +--- diff --git a/_collections/_books/refaktoryzacja-ulepszanie-struktury-istniejacego-kodu.html b/_collections/_books/refaktoryzacja-ulepszanie-struktury-istniejacego-kodu.html new file mode 100644 index 00000000..2f61c55b --- /dev/null +++ b/_collections/_books/refaktoryzacja-ulepszanie-struktury-istniejacego-kodu.html @@ -0,0 +1,20 @@ +--- +title-shortcut: 'Refaktoryzacja. Ulepszanie struktury istniejącego kodu' +title: 'Refaktoryzacja. Ulepszanie struktury istniejącego kodu' +title-of-original: "Refactoring: Improving the Design of Existing Code" +year-of-publishment: 1999 +authors: + - 'Martin Fowler' + - 'Kent Beck' + - 'John Brant' + - 'William Opdyke' + - 'Don Roberts' + - 'Erich Gamma' +--- + + + + + + + diff --git a/_collections/_books/rest.html b/_collections/_books/rest.html new file mode 100644 index 00000000..c7ccea9b --- /dev/null +++ b/_collections/_books/rest.html @@ -0,0 +1,10 @@ +--- +title-shortcut: 'REST' +title: 'REST. Najlepsze praktyki i wzorce w języku Java' +title-of-original: "RESTful Java Patterns and Best Practices" +year-of-publishment: 2015 +authors: + - 'Bhakti Mehta' +langs: java +tags: rest +--- diff --git a/_collections/_books/scala-nauka-programowania.html b/_collections/_books/scala-nauka-programowania.html new file mode 100644 index 00000000..133b560d --- /dev/null +++ b/_collections/_books/scala-nauka-programowania.html @@ -0,0 +1,9 @@ +--- +title-shortcut: 'Scala. Nauka programowania' +title: 'Scala. Nauka programowania' +title-of-original: "Learning Scala Programming" +year-of-publishment: 2018 +authors: + - 'Vikash Sharma' +langs: scala +--- diff --git a/_collections/_books/selenium.html b/_collections/_books/selenium.html new file mode 100644 index 00000000..f43b2b30 --- /dev/null +++ b/_collections/_books/selenium.html @@ -0,0 +1,10 @@ +--- +title-shortcut: 'Selenium' +title: 'Selenium. Automatyczne testowanie aplikacji' +title-of-original: "Selenium Essentials" +year-of-publishment: 2015 +authors: + - 'Prashanth' +langs: java +libs: selenium +--- diff --git a/_collections/_books/spark.html b/_collections/_books/spark.html new file mode 100644 index 00000000..a682d25b --- /dev/null +++ b/_collections/_books/spark.html @@ -0,0 +1,13 @@ +--- +title-shortcut: 'Spark' +title: 'Spark. Zaawansowana analiza danych' +title-of-original: "Advanced Analytics with Spark" +year-of-publishment: 2015 +authors: + - 'Sandy Ryza' + - 'Uri Laserson' + - 'Sean Owen' + - 'Josh Wills' +langs: scala +libs: spark +--- diff --git a/_collections/_books/structura-i-interpretacja-programow-komputerowych.html b/_collections/_books/structura-i-interpretacja-programow-komputerowych.html new file mode 100644 index 00000000..39b3866b --- /dev/null +++ b/_collections/_books/structura-i-interpretacja-programow-komputerowych.html @@ -0,0 +1,11 @@ +--- +title-shortcut: 'Struktura i interpretacja programów komputerowych' +title: 'Struktura i interpretacja programów komputerowych. Klasyka informatyki' +title-of-original: "Structure and Interpretation of Computer Programs" +year-of-publishment: 1996 +authors: + - 'Harold Abelson' + - 'Gerald Jay Sussman' + - 'Julie Sussman' +langs: lisp scheme +--- diff --git a/_collections/_books/tdd.html b/_collections/_books/tdd.html new file mode 100644 index 00000000..918ad29f --- /dev/null +++ b/_collections/_books/tdd.html @@ -0,0 +1,11 @@ +--- +title-shortcut: 'TDD' +title: 'TDD. Programowanie w Javie sterowanie testami' +title-of-original: "Test-Driven Java Development" +year-of-publishment: 2015 +authors: + - 'Viktor Farcic' + - 'Alex Garcia' +langs: java +libs: junit +--- diff --git a/_collections/_books/testuj-oprogramowanie-jak-google.html b/_collections/_books/testuj-oprogramowanie-jak-google.html new file mode 100644 index 00000000..f929de0c --- /dev/null +++ b/_collections/_books/testuj-oprogramowanie-jak-google.html @@ -0,0 +1,10 @@ +--- +title-shortcut: 'Testuj oprogramowanie jak Google' +title: 'Testuj oprogramowanie jak Google. Metody automatyzacji' +title-of-original: "How Google Tests Software" +year-of-publishment: 2012 +authors: + - 'James A. Whittaker' + - 'Jason Arbon' + - 'Jeff Carollo' +--- diff --git a/_collections/_books/zwinne-wytwarzanie-oprogramowania.html b/_collections/_books/zwinne-wytwarzanie-oprogramowania.html new file mode 100644 index 00000000..93d58d1a --- /dev/null +++ b/_collections/_books/zwinne-wytwarzanie-oprogramowania.html @@ -0,0 +1,8 @@ +--- +title-shortcut: 'Zwinne wytwarzanie oprogramowania' +title: 'Zwinne wytwarzanie oprogramowania. Najlepsze zasady, wzorce i praktyki' +title-of-original: "Agile Software Development, principles, Patterns and Practices" +year-of-publishment: 2003 +authors: + - 'Robert C. Martin' +--- diff --git a/_collections/_categories/cli.html b/_collections/_categories/cli.html new file mode 100644 index 00000000..b32f8a9a --- /dev/null +++ b/_collections/_categories/cli.html @@ -0,0 +1,4 @@ +--- +category: cli +--- +Ang. command line interpreter/interface, czyli wiersz poleceń. diff --git a/_collections/_categories/haskell-eta.html b/_collections/_categories/haskell-eta.html new file mode 100644 index 00000000..6b786acc --- /dev/null +++ b/_collections/_categories/haskell-eta.html @@ -0,0 +1,4 @@ +--- +category: haskell-eta +redirect_from: +--- diff --git a/_collections/_categories/java.html b/_collections/_categories/java.html new file mode 100644 index 00000000..762460b8 --- /dev/null +++ b/_collections/_categories/java.html @@ -0,0 +1,3 @@ +--- +category: java +--- diff --git a/_collections/_categories/jekyll.html b/_collections/_categories/jekyll.html new file mode 100644 index 00000000..2bcceae3 --- /dev/null +++ b/_collections/_categories/jekyll.html @@ -0,0 +1,4 @@ +--- +category: jekyll +--- +Opis walki z generatorem statycznych stron Jekyll i powstawania tematu WriteOnlyDoc. diff --git a/_collections/_categories/programming.html b/_collections/_categories/programming.html new file mode 100644 index 00000000..2be6a29b --- /dev/null +++ b/_collections/_categories/programming.html @@ -0,0 +1,4 @@ +--- +category: programming +--- +Techniczne opowieści o programowaniu i językach programowania. diff --git a/_collections/_categories/relationships.html b/_collections/_categories/relationships.html new file mode 100644 index 00000000..027c07d5 --- /dev/null +++ b/_collections/_categories/relationships.html @@ -0,0 +1,4 @@ +--- +category: relationships +--- +Relacje z wydarzeń diff --git a/_collections/_categories/rust.html b/_collections/_categories/rust.html new file mode 100644 index 00000000..d57c1949 --- /dev/null +++ b/_collections/_categories/rust.html @@ -0,0 +1,4 @@ +--- +category: rust +redirect_from: +--- diff --git a/_collections/_categories/scala-jvm.html b/_collections/_categories/scala-jvm.html new file mode 100644 index 00000000..7cb6b966 --- /dev/null +++ b/_collections/_categories/scala-jvm.html @@ -0,0 +1,6 @@ +--- +category: scala-jvm +redirect_from: +--- +Opis powstawania projektu hyde +w języku programowania Scala, diff --git a/_collections/_categories/scala-native.html b/_collections/_categories/scala-native.html new file mode 100644 index 00000000..a3bdcbb7 --- /dev/null +++ b/_collections/_categories/scala-native.html @@ -0,0 +1,6 @@ +--- +category: scala-native +--- +Opis powstawania projektu resentiment +w języku programowania Scala, +Scala.js i Scala native. diff --git a/_collections/_categories/scheme-racket.html b/_collections/_categories/scheme-racket.html new file mode 100644 index 00000000..fc7c4f50 --- /dev/null +++ b/_collections/_categories/scheme-racket.html @@ -0,0 +1,4 @@ +--- +category: scheme-racket +redirect_from: +--- diff --git a/_collections/_categories/thoughts.html b/_collections/_categories/thoughts.html new file mode 100644 index 00000000..901c832b --- /dev/null +++ b/_collections/_categories/thoughts.html @@ -0,0 +1,4 @@ +--- +category: thoughts +--- +Przemyślenia niedokońca technicznie. diff --git a/_collections/_eso/beatnik.html b/_collections/_eso/beatnik.html new file mode 100644 index 00000000..b1cfa468 --- /dev/null +++ b/_collections/_eso/beatnik.html @@ -0,0 +1,5 @@ +--- +eso: beatnik +title: Beatnik +tags: esolang +--- diff --git a/_collections/_eso/brainfuck.html b/_collections/_eso/brainfuck.html new file mode 100644 index 00000000..67c4a24d --- /dev/null +++ b/_collections/_eso/brainfuck.html @@ -0,0 +1,7 @@ +--- +eso: brainfuck +title: BrainFuck +tags: esolang +color: rainbow +--- +🌈 diff --git a/_collections/_eso/eas.html b/_collections/_eso/eas.html new file mode 100644 index 00000000..6e9f39fd --- /dev/null +++ b/_collections/_eso/eas.html @@ -0,0 +1,7 @@ +--- +eso: ets +title: EAS +tags: assembler +color: red +--- +❤️ Assembler dla ETA diff --git a/_collections/_eso/esoassembly.html b/_collections/_eso/esoassembly.html new file mode 100644 index 00000000..a2ebf478 --- /dev/null +++ b/_collections/_eso/esoassembly.html @@ -0,0 +1,7 @@ +--- +lang: esoassembly +title: EsoAssembly +description: '' +redirect_from: +- langs/easm +--- diff --git a/_collections/_eso/eta.html b/_collections/_eso/eta.html new file mode 100644 index 00000000..7828a0b7 --- /dev/null +++ b/_collections/_eso/eta.html @@ -0,0 +1,7 @@ +--- +eso: eta +title: ETA +tags: esolang +color: red +--- +❤️ diff --git a/_collections/_eso/false.html b/_collections/_eso/false.html new file mode 100644 index 00000000..1ea26cbf --- /dev/null +++ b/_collections/_eso/false.html @@ -0,0 +1,18 @@ +--- +eso: false +title: False +tags: esolang +--- + +Istnieją w Haskellu dwie implementacje ezoterycznego języka False: + + +Przykładowy program: +
+{[n: 0 1 [n;0=~][$2o+n;1-n:]# %%]f: 300f;!}
+[0 1 @ [0=~][1o3o+\1-]# %%%]f: 300f;!
+{4 0 1 @ 1o 3o + \ 1 -}
+
diff --git a/_collections/_eso/funge.html b/_collections/_eso/funge.html new file mode 100644 index 00000000..3b41748e --- /dev/null +++ b/_collections/_eso/funge.html @@ -0,0 +1,8 @@ +--- +eso: funge +title: Funge +tags: compiler esolang +langs: scheme +color: yellow +--- +💛 Kompilator podzbioru Scheme do Funge diff --git a/_collections/_eso/piet.html b/_collections/_eso/piet.html new file mode 100644 index 00000000..61164450 --- /dev/null +++ b/_collections/_eso/piet.html @@ -0,0 +1,12 @@ +--- +eso: piet +title: Piet +tags: esolang +color: green +--- +💚 + +Istnieje jeden interpreter ezoterycznego języka Piet napisany w Haskellu: + diff --git a/_collections/_eso/sponge.html b/_collections/_eso/sponge.html new file mode 100644 index 00000000..3bfbc0a3 --- /dev/null +++ b/_collections/_eso/sponge.html @@ -0,0 +1,7 @@ +--- +eso: sponge +title: Sponge +tags: esolang +color: yellow +--- +💛 Compiler Subset of Scheme to BeFunge98 diff --git a/_collections/_eso/sqasm.html b/_collections/_eso/sqasm.html new file mode 100644 index 00000000..e476c3e8 --- /dev/null +++ b/_collections/_eso/sqasm.html @@ -0,0 +1,7 @@ +--- +eso: sqasm +title: SqAsm +tags: assembler +color: blue +--- +💙 Assembler dla SubLeq diff --git a/_collections/_eso/subleq.html b/_collections/_eso/subleq.html new file mode 100644 index 00000000..28b1682d --- /dev/null +++ b/_collections/_eso/subleq.html @@ -0,0 +1,7 @@ +--- +eso: subleq +title: SubLeq +tags: esolang +color: blue +--- +💙 diff --git a/_collections/_eso/wasm.html b/_collections/_eso/wasm.html new file mode 100644 index 00000000..32ad266f --- /dev/null +++ b/_collections/_eso/wasm.html @@ -0,0 +1,7 @@ +--- +eso: wasm +title: WAsm +tags: assembler +color: black +--- +🖤 Assembler Maszyny W diff --git a/_collections/_eso/whitespace.html b/_collections/_eso/whitespace.html new file mode 100644 index 00000000..95288203 --- /dev/null +++ b/_collections/_eso/whitespace.html @@ -0,0 +1,15 @@ +--- +eso: whitespace +title: WhiteSpace +tags: esolang +color: white +--- +🤍 + +Istnieją cztery interpretery ezoterycznego języka WhiteSpace napisane w Haskellu: + diff --git a/_collections/_eso/wsa.html b/_collections/_eso/wsa.html new file mode 100644 index 00000000..a9aaf7d9 --- /dev/null +++ b/_collections/_eso/wsa.html @@ -0,0 +1,7 @@ +--- +eso: wsa +title: WSA +tags: assembler +color: white +--- +🤍 Assembler dla WhiteSpace diff --git a/_collections/_langs/agda.html b/_collections/_langs/agda.html new file mode 100644 index 00000000..30c0dee8 --- /dev/null +++ b/_collections/_langs/agda.html @@ -0,0 +1,10 @@ +--- +lang: agda +title: Agda +description: +--- + diff --git a/_collections/_langs/ams-js.html b/_collections/_langs/ams-js.html new file mode 100644 index 00000000..28e6d860 --- /dev/null +++ b/_collections/_langs/ams-js.html @@ -0,0 +1,5 @@ +--- +lang: ams-js +title: asm.js +description: '' +--- diff --git a/_collections/_langs/awk.html b/_collections/_langs/awk.html new file mode 100644 index 00000000..d871292d --- /dev/null +++ b/_collections/_langs/awk.html @@ -0,0 +1,17 @@ +--- +lang: awk +title: AWK +description: dynamicznie typowany, skryptowy język programowania. +--- + + +

Blogi

+ diff --git a/_collections/_langs/ceylon.html b/_collections/_langs/ceylon.html new file mode 100644 index 00000000..82074b50 --- /dev/null +++ b/_collections/_langs/ceylon.html @@ -0,0 +1,16 @@ +--- +lang: ceylon +title: Ceylon +description: statycznie typowany język programowania kompliwany do kodu maszynowego Javy. +--- + diff --git a/_collections/_langs/clojure.html b/_collections/_langs/clojure.html new file mode 100644 index 00000000..4311cf28 --- /dev/null +++ b/_collections/_langs/clojure.html @@ -0,0 +1,52 @@ +--- +lang: clojure +title: Clojure +description: 'obiektowo-funkcyjny dialekt funkcyjnego języka programowania Lisp kompilowany do kodu bajtowego Javy.' +--- + + +Istnieją także poboczne kompilatory i transpilatory języka Clojure: + + +

Tutoriale i książki

+ diff --git a/_collections/_langs/coffeescript.html b/_collections/_langs/coffeescript.html new file mode 100644 index 00000000..a4bf3929 --- /dev/null +++ b/_collections/_langs/coffeescript.html @@ -0,0 +1,21 @@ +--- +lang: coffeescript +title: CoffeeScript +description: 'dynamicznie typowany język programowania transpilowany do języka JavaScript.' +redirect_from: +- langs/cs +--- + diff --git a/_collections/_langs/common-lisp.html b/_collections/_langs/common-lisp.html new file mode 100644 index 00000000..30733feb --- /dev/null +++ b/_collections/_langs/common-lisp.html @@ -0,0 +1,35 @@ +--- +lang: common-lisp +title: Common Lisp +description: 'obiektowo-funkcyjny standard funkcyjnego języka programowania Lisp.' +redirect_from: +- langs/cl +--- + + +

Blogi

+ + +

Inne

+ diff --git a/_collections/_langs/coq.html b/_collections/_langs/coq.html new file mode 100644 index 00000000..b0cae685 --- /dev/null +++ b/_collections/_langs/coq.html @@ -0,0 +1,13 @@ +--- +lang: coq +title: Coq +description: +--- + \ No newline at end of file diff --git a/_collections/_langs/crystal.html b/_collections/_langs/crystal.html new file mode 100644 index 00000000..57d1e28f --- /dev/null +++ b/_collections/_langs/crystal.html @@ -0,0 +1,19 @@ +--- +lang: crystal +title: Crystal +description: statycznie typowany, natywny język programowania ze składnią inspirowaną językiem Ruby. +--- + diff --git a/_collections/_langs/dart.html b/_collections/_langs/dart.html new file mode 100644 index 00000000..429b4bc3 --- /dev/null +++ b/_collections/_langs/dart.html @@ -0,0 +1,16 @@ +--- +lang: dart +title: Dart +description: statycznie typowany język programowania +--- + diff --git a/_collections/_langs/dc.html b/_collections/_langs/dc.html new file mode 100644 index 00000000..d47be398 --- /dev/null +++ b/_collections/_langs/dc.html @@ -0,0 +1,5 @@ +--- +lang: dc +title: DC +description: '' +--- \ No newline at end of file diff --git a/_collections/_langs/eiffel.html b/_collections/_langs/eiffel.html new file mode 100644 index 00000000..fff7e457 --- /dev/null +++ b/_collections/_langs/eiffel.html @@ -0,0 +1,13 @@ +--- +lang: eiffel +title: Eiffel +description: statycznie typowany, obiektowy język programowania. +--- + diff --git a/_collections/_langs/elixir.html b/_collections/_langs/elixir.html new file mode 100644 index 00000000..30544b2b --- /dev/null +++ b/_collections/_langs/elixir.html @@ -0,0 +1,19 @@ +--- +lang: elixir +title: Elixir +description: dynamicznie i silnie typowany oraz funkcyjny i współbieżny język programowania działający na maszynie wirtualnej Erlanga ze składnią inspirowaną językiem Ruby. +--- + diff --git a/_collections/_langs/elm.html b/_collections/_langs/elm.html new file mode 100644 index 00000000..204f99e4 --- /dev/null +++ b/_collections/_langs/elm.html @@ -0,0 +1,33 @@ +--- +lang: elm +title: Elm +description: 'język funkcyjny transpilowany do JS ispirowany językami ML i Haskell.' +--- + + +

Tutoriale i książki

+ + +

Blogi

+ diff --git a/_collections/_langs/emacs-lisp.html b/_collections/_langs/emacs-lisp.html new file mode 100644 index 00000000..c4e6c9be --- /dev/null +++ b/_collections/_langs/emacs-lisp.html @@ -0,0 +1,20 @@ +--- +lang: emacs-lisp +title: Emacs Lisp +description: 'Elisp, dialekt języka programowania Lisp używany do pisania rozszerzeń i skryptów edytora Emacs.' +redirect_from: +- langs/el +- langs/elc +- langs/elisp +--- + diff --git a/_collections/_langs/erlang.html b/_collections/_langs/erlang.html new file mode 100644 index 00000000..97479219 --- /dev/null +++ b/_collections/_langs/erlang.html @@ -0,0 +1,13 @@ +--- +lang: erlang +title: Erlang +description: dynamicznie i silnie typowany oraz funkcyjny i współbieżny język programowania działający na maszynie wirtualnej Erlanga +--- + diff --git a/_collections/_langs/eta.html b/_collections/_langs/eta.html new file mode 100644 index 00000000..3760e95f --- /dev/null +++ b/_collections/_langs/eta.html @@ -0,0 +1,41 @@ +--- +lang: eta +title: Eta +description: 'implementacja czysto-funkcyjnego języka programowania Haskell kompilowana do kodu bajtowego Javy.' +--- + + +

Wykłady i prezentacje

+ diff --git a/_collections/_langs/forth.html b/_collections/_langs/forth.html new file mode 100644 index 00000000..9e8191ef --- /dev/null +++ b/_collections/_langs/forth.html @@ -0,0 +1,5 @@ +--- +lang: forth +title: Forth +description: '' +--- diff --git a/_collections/_langs/frege.html b/_collections/_langs/frege.html new file mode 100644 index 00000000..8c503693 --- /dev/null +++ b/_collections/_langs/frege.html @@ -0,0 +1,20 @@ +--- +lang: frege +title: Frege +description: 'dialekt czysto-funkcyjnego języka programowania Haskell kompilowany do kodu bajtowego Javy.' +--- + + +

Nagrania

+ diff --git a/_collections/_langs/fsharp.html b/_collections/_langs/fsharp.html new file mode 100644 index 00000000..28977a6a --- /dev/null +++ b/_collections/_langs/fsharp.html @@ -0,0 +1,16 @@ +--- +lang: fsharp +title: F# +description: statycznie typowany, obiektowo-funkcyjny język programowania. Dialekt języka OCaml +--- + diff --git a/_collections/_langs/genie.html b/_collections/_langs/genie.html new file mode 100644 index 00000000..1fe51174 --- /dev/null +++ b/_collections/_langs/genie.html @@ -0,0 +1,13 @@ +--- +lang: genie +title: Genie +description: statycznie typowany, natywny i obiektowy język programowania transpilowany do C. +--- + diff --git a/_collections/_langs/go.html b/_collections/_langs/go.html new file mode 100644 index 00000000..97b153c0 --- /dev/null +++ b/_collections/_langs/go.html @@ -0,0 +1,16 @@ +--- +lang: go +title: Go +description: statycznie typowany, natywny język programowania. +--- + diff --git a/_collections/_langs/hamler.html b/_collections/_langs/hamler.html new file mode 100644 index 00000000..a3124e7b --- /dev/null +++ b/_collections/_langs/hamler.html @@ -0,0 +1,15 @@ +--- +lang: hamler +title: hamler +description: 'dialekt funkcyjnego języka programowania Haskell działający na maszynie wirtualnej Erlanga.' +redirect_from: +- langs/ps +--- + \ No newline at end of file diff --git a/_collections/_langs/haskell.html b/_collections/_langs/haskell.html new file mode 100644 index 00000000..25020d92 --- /dev/null +++ b/_collections/_langs/haskell.html @@ -0,0 +1,85 @@ +--- +lang: haskell +title: Haskell +description: 'statycznie typowany, natywny i czysto-funkcyjny język programowania.' +redirect_from: +- langs/hs +- langs/lhs +--- + + +

Niestandardowe implementacje i dialekty

+ diff --git a/_collections/_langs/idris.html b/_collections/_langs/idris.html new file mode 100644 index 00000000..37d9fe47 --- /dev/null +++ b/_collections/_langs/idris.html @@ -0,0 +1,23 @@ +--- +lang: idris +title: Idris +description: 'statycznie typowany, natywny i czysto-funkcyjny język programowania. Prawdopodobnie następca języka Haskell.' +--- + + +

Książki

+ diff --git a/_collections/_langs/java.html b/_collections/_langs/java.html new file mode 100644 index 00000000..461b84c8 --- /dev/null +++ b/_collections/_langs/java.html @@ -0,0 +1,5 @@ +--- +lang: java +title: Java +description: statycznie typowany język programowania kompilowany do kodu maszynowego Javy. +--- \ No newline at end of file diff --git a/_collections/_langs/javascript.html b/_collections/_langs/javascript.html new file mode 100644 index 00000000..4759a073 --- /dev/null +++ b/_collections/_langs/javascript.html @@ -0,0 +1,7 @@ +--- +lang: javascript +title: JavaScript +description: 'dynamicznie i słabo typowany, skryptowy język programowania.' +redirect_from: +- langs/js +--- diff --git a/_collections/_langs/joy.html b/_collections/_langs/joy.html new file mode 100644 index 00000000..4dab6dcb --- /dev/null +++ b/_collections/_langs/joy.html @@ -0,0 +1,13 @@ +--- +lang: joy +title: Joy +description: funkcyjny, stosowy, dynamicznie typowany język programowania +--- + diff --git a/_collections/_langs/julia.html b/_collections/_langs/julia.html new file mode 100644 index 00000000..21dddc8d --- /dev/null +++ b/_collections/_langs/julia.html @@ -0,0 +1,13 @@ +--- +lang: julia +title: Julia +description: dynamicznie typowany język przeznaczony do wysokowydajnej analizy numerycznej i nauk obliczeniowych. +--- + diff --git a/_collections/_langs/kotlin.html b/_collections/_langs/kotlin.html new file mode 100644 index 00000000..2e33c9a1 --- /dev/null +++ b/_collections/_langs/kotlin.html @@ -0,0 +1,26 @@ +--- +lang: kotlin +title: Kotlin +description: statycznie typowany język programowania kompilowany do kodu maszynowego Javy. +--- + + +

Nagrania

+ \ No newline at end of file diff --git a/_collections/_langs/lisp.html b/_collections/_langs/lisp.html new file mode 100644 index 00000000..d05d4e35 --- /dev/null +++ b/_collections/_langs/lisp.html @@ -0,0 +1,29 @@ +--- +lang: lisp +title: Lisp +description: dynamicznie typowany, funkcyjny język programowania. +--- +Pięć głównych dialektów to: +
    +
  1. + Scheme - minimalistyczny, + mocno funkcyjny (rekurencja ogonkowa i pełne kontunuacje) Lisp wymyślony w MIT do katowania studentów +
  2. +
  3. + Racket - dialekt Scheme używany do zastosowań naukowych +
  4. +
  5. + Clojure - dialekt Lispa, + mocno podobny do Scheme, + zoptymalizowany do działania na JVM + i czerpiący mocno z języka Haskell +
  6. +
  7. + Common Lisp - wszystkomający, + obiektowo-funkcyjny (Common Lisp Object System) Lisp +
  8. +
  9. + Emacs Lisp - dialekt Lispa, + mocno podobny do Common Lisp, używany w edytorze Emacs +
  10. +
diff --git a/_collections/_langs/livescript.html b/_collections/_langs/livescript.html new file mode 100644 index 00000000..5e28f92f --- /dev/null +++ b/_collections/_langs/livescript.html @@ -0,0 +1,18 @@ +--- +lang: livescript +title: LiveScript +description: 'dynamicznie i słabo typowany język programowania transpilowany do języka JavaScript.' +redirect_from: +- langs/ls +--- + diff --git a/_collections/_langs/lua.html b/_collections/_langs/lua.html new file mode 100644 index 00000000..73d84932 --- /dev/null +++ b/_collections/_langs/lua.html @@ -0,0 +1,22 @@ +--- +lang: lua +title: Lua +description: dynamicznie typowany, skryptowy język programowania. +--- + diff --git a/_collections/_langs/meta-language.html b/_collections/_langs/meta-language.html new file mode 100644 index 00000000..47ff8939 --- /dev/null +++ b/_collections/_langs/meta-language.html @@ -0,0 +1,49 @@ +--- +lang: meta-language +title: Meta Language +description: 'ML, rodzina statycznie typowanych języków funkcyjnych. Jako jeden z pierwszych posiadał typy polimorficzne umożliwiajace metaprogramowanie. Zaprojektowany jako LISP z typami.' +redirect_from: +- posts-by-langs/meta-language +- langs/ml +- langs/sml +--- +

Dialekty języka ML

+
    +
  1. + OCaml - prawdopodobnie pierwszy statycznie typowany język wszystkomający (obiektowo-funkcyjny). +
  2. +
  3. + Standard ML, (SML) - ustandaryzowana wersja języka. +
  4. +
  5. + Concurrent ML, (CML) - dialekt Standard ML posiadający rozszerzenia do programowania współbierznego. +
  6. +
  7. + Dependent ML, (DML) - eksperymentalna wersja ML posiadająca typy zależne. +
  8. +
  9. + Lazy ML, (LML) - język ML z leniwą ewaluacją kompilowany do kodu natywnego. + Jeden z protoplastów języka Haskell +
  10. +
  11. + MacroML - eksperymentalna wersja ML posiadająca makra inspirowane makrami z języka Scheme +
  12. +
  13. + Elm - język transpilowany do JS, inspirowany językami ML i Haskell. +
  14. +
  15. + LinearML - ML działąjący bez GC +
  16. +
+ +

Kursy

+ + + diff --git a/_collections/_langs/mouse.html b/_collections/_langs/mouse.html new file mode 100644 index 00000000..620b98a4 --- /dev/null +++ b/_collections/_langs/mouse.html @@ -0,0 +1,10 @@ +--- +lang: mouse +title: Mouse +description: '' +--- + diff --git a/_collections/_langs/ocaml.html b/_collections/_langs/ocaml.html new file mode 100644 index 00000000..b26a1c9e --- /dev/null +++ b/_collections/_langs/ocaml.html @@ -0,0 +1,55 @@ +--- +lang: ocaml +title: OCaml +description: 'Obiektowe rozwinięcie języka programowania ML i pradopodobnie pierwszy statycznie typowany język wszystkomający (obiektowo-funkcyjny)' +redirect_from: +- langs/caml +- langs/mli +--- + + +

Blogi i youtube

+ + +

Dialekty języka OCaml i języki inspirowane nim

+
    +
  1. + Scala - język programowania na wirtualną maszynę Javy + inspirowany językiem OCaml. + Podobno co wersję Scali Martina Odersky zastanawia się czy nie zastąpić wąsatych nawiasów wcięciami jak w języku OCaml. +
  2. +
  3. + F# -implementacja języka OCaml na platformę .Net która powoli staje się nowym dialektem i językiem. +
  4. +
  5. + ReasonML - dialekt języka OCaml + kompilowany do JS + za pomocą BuckleScript. +
  6. +
diff --git a/_collections/_langs/perl.html b/_collections/_langs/perl.html new file mode 100644 index 00000000..20d07cd2 --- /dev/null +++ b/_collections/_langs/perl.html @@ -0,0 +1,22 @@ +--- +lang: perl +title: Perl +description: dynamicznie i słabo typowany, skryptowy język programowania. +--- + \ No newline at end of file diff --git a/_collections/_langs/pony.html b/_collections/_langs/pony.html new file mode 100644 index 00000000..4fc4aeed --- /dev/null +++ b/_collections/_langs/pony.html @@ -0,0 +1,23 @@ +--- +lang: pony +title: Pony +description: natywny język programowania. +--- + + +

Artykuły i youtube

+ diff --git a/_collections/_langs/postscript.html b/_collections/_langs/postscript.html new file mode 100644 index 00000000..faedd241 --- /dev/null +++ b/_collections/_langs/postscript.html @@ -0,0 +1,10 @@ +--- +lang: postscript +title: PostScript +description: '' +--- + diff --git a/_collections/_langs/prolog.html b/_collections/_langs/prolog.html new file mode 100644 index 00000000..6823846d --- /dev/null +++ b/_collections/_langs/prolog.html @@ -0,0 +1,27 @@ +--- +lang: prolog +title: Prolog +description: język programowania logicznego. +--- + +

Blogi

+ diff --git a/_collections/_langs/purescript.html b/_collections/_langs/purescript.html new file mode 100644 index 00000000..36a1cd03 --- /dev/null +++ b/_collections/_langs/purescript.html @@ -0,0 +1,21 @@ +--- +lang: purescript +title: PureScript +description: 'dialekt funkcyjnego języka programowania Haskell transpilowany do języka JavaScript.' +redirect_from: +- langs/ps +--- + \ No newline at end of file diff --git a/_collections/_langs/python.html b/_collections/_langs/python.html new file mode 100644 index 00000000..cd48edc5 --- /dev/null +++ b/_collections/_langs/python.html @@ -0,0 +1,16 @@ +--- +lang: python +title: Python +description: dynamicznie typowany, skryptowy język programowania. +--- + diff --git a/_collections/_langs/racket.html b/_collections/_langs/racket.html new file mode 100644 index 00000000..8780ba25 --- /dev/null +++ b/_collections/_langs/racket.html @@ -0,0 +1,19 @@ +--- +lang: racket +title: Racket +description: statycznie i dynamicznie typowany, funkcyjno-obiektowy dialekt języka programowania Scheme. +--- + diff --git a/_collections/_langs/reasonml.html b/_collections/_langs/reasonml.html new file mode 100644 index 00000000..61b5dcf8 --- /dev/null +++ b/_collections/_langs/reasonml.html @@ -0,0 +1,35 @@ +--- +lang: reasonml +title: ReasonML +description: 'Reason, rozszerzenie obiektowo-funkcyjnego języka programowania OCaml transpilowane do języka JavaScript.' +redirect_from: +- langs/reason +- langs/re +--- + + +

YouTube

+ diff --git a/_collections/_langs/rpl.html b/_collections/_langs/rpl.html new file mode 100644 index 00000000..29b794bc --- /dev/null +++ b/_collections/_langs/rpl.html @@ -0,0 +1,5 @@ +--- +lang: rpl +title: RPL +description: '' +--- diff --git a/_collections/_langs/ruby.html b/_collections/_langs/ruby.html new file mode 100644 index 00000000..1c7e6554 --- /dev/null +++ b/_collections/_langs/ruby.html @@ -0,0 +1,22 @@ +--- +lang: ruby +title: Ruby +description: dynamicznie typowany, w pełni obiektowy oraz interpretowany język programowania. +--- + \ No newline at end of file diff --git a/_collections/_langs/rust.html b/_collections/_langs/rust.html new file mode 100644 index 00000000..966d9557 --- /dev/null +++ b/_collections/_langs/rust.html @@ -0,0 +1,22 @@ +--- +lang: rust +title: Rust +description: statycznie typowany, natywny język programowania. +--- + diff --git a/_collections/_langs/sather.html b/_collections/_langs/sather.html new file mode 100644 index 00000000..bb8d27bc --- /dev/null +++ b/_collections/_langs/sather.html @@ -0,0 +1,13 @@ +--- +lang: sather +title: Sather +description: statycznie typowany, obiektowy język programowania. +--- + diff --git a/_collections/_langs/scala.html b/_collections/_langs/scala.html new file mode 100644 index 00000000..5611004d --- /dev/null +++ b/_collections/_langs/scala.html @@ -0,0 +1,32 @@ +--- +lang: scala +title: Scala +description: statycznie typowany, obiektowo-funkcyjny język programowania kompilowany do kodu maszynowego Javy inspirowany językami OCaml, Erlang i Haskell. +--- + + +

Tutoriale i książki

+ diff --git a/_collections/_langs/scheme.html b/_collections/_langs/scheme.html new file mode 100644 index 00000000..f3fe0828 --- /dev/null +++ b/_collections/_langs/scheme.html @@ -0,0 +1,131 @@ +--- +lang: scheme +title: Scheme +description: 'standard funkcyjnego języka programowania Lisp.' +--- + + +

Książki

+ + +

Implementacja rozwijane

+Racket wszystkomający dialekt.
+ +CHICKEN scheme - embedded intepreter z kontunuacjami + + +Chibi-Scheme - nowy embedded intepreter + + +Guile Scheme - wersja Scheme z łatwą integracją z C oparty na SCM + + +

Implementacje historyczne

+s7 - embedded intepreter oparty na TinyScheme + + +TinyScheme - embedded intepreter aktualnie używany w Gimpie + + +Scsh (a Scheme Shell) - powłoka systemowa oparta na Scheme 48 + + +Scheme 48 - interpreter będący podstawą powłoki Scheme Shell + + +SCM - wersja scheme oparta na SIOD + + +SIOD - embedded intepreter pierwotnie używany w Gimpie + + +PreScheme - Niskopoziomowy Scheme działąjący bez GC diff --git a/_collections/_langs/smalltalk.html b/_collections/_langs/smalltalk.html new file mode 100644 index 00000000..9dd3b7df --- /dev/null +++ b/_collections/_langs/smalltalk.html @@ -0,0 +1,32 @@ +--- +lang: smalltalk +title: +description: dynamicznie typowany, w pełni obiektowy, reflektywny języki programowania. +--- + +

Książki

+ +

Implementacje

+Squeak -implementacja języka Smalltalk. + diff --git a/_collections/_langs/tcl.html b/_collections/_langs/tcl.html new file mode 100644 index 00000000..eafcef0a --- /dev/null +++ b/_collections/_langs/tcl.html @@ -0,0 +1,25 @@ +--- +lang: tcl +title: Tcl +description: 'dynamicznie typowany, skryptowy język programowania inspirowany językiem Lisp.' +--- + +

Tutoriale

+ \ No newline at end of file diff --git a/_collections/_langs/typescript.html b/_collections/_langs/typescript.html new file mode 100644 index 00000000..d4a8e0d7 --- /dev/null +++ b/_collections/_langs/typescript.html @@ -0,0 +1,21 @@ +--- +lang: typescript +title: TypeScript +description: 'statycznie typowany język programowania transpilowany do języka JavaScript.' +redirect_from: +- langs/ts +--- + diff --git a/_collections/_langs/vala.html b/_collections/_langs/vala.html new file mode 100644 index 00000000..0c8c1d26 --- /dev/null +++ b/_collections/_langs/vala.html @@ -0,0 +1,16 @@ +--- +lang: vala +title: Vala +description: statycznie typowany, natywny i obiektowy język programowania transpilowany do C. +--- + diff --git a/_collections/_langs/webassembly.html b/_collections/_langs/webassembly.html new file mode 100644 index 00000000..974c2912 --- /dev/null +++ b/_collections/_langs/webassembly.html @@ -0,0 +1,7 @@ +--- +lang: webassembly +title: WebAssembly +description: '' +redirect_from: +- langs/wasm +--- diff --git a/_collections/_langs/zig.html b/_collections/_langs/zig.html new file mode 100644 index 00000000..245a12bf --- /dev/null +++ b/_collections/_langs/zig.html @@ -0,0 +1,5 @@ +--- +lang: zig +title: Zig +description: '' +--- diff --git a/_collections/_libs/akka-http.html b/_collections/_libs/akka-http.html new file mode 100644 index 00000000..e47e5f41 --- /dev/null +++ b/_collections/_libs/akka-http.html @@ -0,0 +1,7 @@ +--- +lib: akka-http +title: Akka HTTP +langs: scala +tags: http +--- +Akka HTTP diff --git a/_collections/_libs/akka-js.html b/_collections/_libs/akka-js.html new file mode 100644 index 00000000..efb7b4a4 --- /dev/null +++ b/_collections/_libs/akka-js.html @@ -0,0 +1,6 @@ +--- +lib: akka-js +title: Akka.js +langs: scala javascript +--- +AKKA.JS diff --git a/_collections/_libs/akka.html b/_collections/_libs/akka.html new file mode 100644 index 00000000..7947e68c --- /dev/null +++ b/_collections/_libs/akka.html @@ -0,0 +1,7 @@ +--- +lib: akka +title: akka +langs: scala +--- +akka - biblioteka dla języka Scala, +która umożliwia programowanie z użyciem aktoróœ w jak w języku Erlang. \ No newline at end of file diff --git a/_collections/_libs/arrow.html b/_collections/_libs/arrow.html new file mode 100644 index 00000000..afc6f171 --- /dev/null +++ b/_collections/_libs/arrow.html @@ -0,0 +1,8 @@ +--- +lib: arrow +title: ARROW +langs: kotlin +tags: fp +--- +ARROW - biblioteka dla języka Kotlin, +która umożliwia programowanie czysto-funkcyjne znane z języka Haskell. \ No newline at end of file diff --git a/_collections/_libs/attoparsec.html b/_collections/_libs/attoparsec.html new file mode 100644 index 00000000..b8b1352c --- /dev/null +++ b/_collections/_libs/attoparsec.html @@ -0,0 +1,21 @@ +--- +lib: attoparsec +title: Attoparsec +langs: haskell eta +tags: parser +--- +AttoParsec - biblioteka do budowania parserów dla języków Haskell i Eta. + diff --git a/_collections/_libs/cats.html b/_collections/_libs/cats.html new file mode 100644 index 00000000..56eab6fa --- /dev/null +++ b/_collections/_libs/cats.html @@ -0,0 +1,8 @@ +--- +lib: cats +title: Cats +langs: scala +tags: fp +--- +Cats - biblioteka dla języka Scala, +która umożliwia programowanie czysto-funkcyjne znane z języka Haskell. \ No newline at end of file diff --git a/_collections/_libs/dagger.html b/_collections/_libs/dagger.html new file mode 100644 index 00000000..f180040e --- /dev/null +++ b/_collections/_libs/dagger.html @@ -0,0 +1,6 @@ +--- +lib: dagger +title: Dagger +langs: java +tags: di +--- diff --git a/_collections/_libs/dropwizard.html b/_collections/_libs/dropwizard.html new file mode 100644 index 00000000..d141346d --- /dev/null +++ b/_collections/_libs/dropwizard.html @@ -0,0 +1,8 @@ +--- +lib: dropwizard +title: DropWizard +langs: java +tags: http +--- + +https://github.com/dropwizard/dropwizard \ No newline at end of file diff --git a/_collections/_libs/earley.html b/_collections/_libs/earley.html new file mode 100644 index 00000000..517ff646 --- /dev/null +++ b/_collections/_libs/earley.html @@ -0,0 +1,7 @@ +--- +lib: earley +title: Earley +langs: haskell +tags: parser +--- +Earley - biblioteka do budowania parserów dla języka Haskell. diff --git a/_collections/_libs/fastparse.html b/_collections/_libs/fastparse.html new file mode 100644 index 00000000..71bb97ee --- /dev/null +++ b/_collections/_libs/fastparse.html @@ -0,0 +1,7 @@ +--- +lib: fastparse +title: FastParse +langs: scala +tags: parser +--- +FastParse - biblioteka do budowania parserów dla języka Scala. diff --git a/_collections/_libs/fastparser.html b/_collections/_libs/fastparser.html new file mode 100644 index 00000000..72048c0a --- /dev/null +++ b/_collections/_libs/fastparser.html @@ -0,0 +1,7 @@ +--- +lib: fastparser +title: FastParser +langs: haskell +tags: parser +--- +FastParser - biblioteka do budowania parserów dla języka Haskell. diff --git a/_collections/_libs/functionaljava.html b/_collections/_libs/functionaljava.html new file mode 100644 index 00000000..15a7fbcc --- /dev/null +++ b/_collections/_libs/functionaljava.html @@ -0,0 +1,10 @@ +--- +lib: functionaljava +title: Functional Java +langs: java +tags: fp +--- +Functional Java - biblioteka dla języka Java, +która umożliwia programowanie czysto-funkcyjne znane z języka Haskell. + +Twitter : @@functionaljava \ No newline at end of file diff --git a/_collections/_libs/gson.html b/_collections/_libs/gson.html new file mode 100644 index 00000000..ee0d6bea --- /dev/null +++ b/_collections/_libs/gson.html @@ -0,0 +1,6 @@ +--- +lib: gson +title: Gson +langs: java +tags: json +--- diff --git a/_collections/_libs/guice.html b/_collections/_libs/guice.html new file mode 100644 index 00000000..bc309587 --- /dev/null +++ b/_collections/_libs/guice.html @@ -0,0 +1,6 @@ +--- +lib: guice +title: Guice +langs: java +tags: di +--- diff --git a/_collections/_libs/happly-alex.html b/_collections/_libs/happly-alex.html new file mode 100644 index 00000000..382e6836 --- /dev/null +++ b/_collections/_libs/happly-alex.html @@ -0,0 +1,21 @@ +--- +lib: happy-alex +title: Happy & Alex +langs: haskell eta +tags: parser +--- +Happy i Alex - biblioteki do budowania parserów dla języków Haskell i Eta. + diff --git a/_collections/_libs/happy-alex.html b/_collections/_libs/happy-alex.html new file mode 100644 index 00000000..382e6836 --- /dev/null +++ b/_collections/_libs/happy-alex.html @@ -0,0 +1,21 @@ +--- +lib: happy-alex +title: Happy & Alex +langs: haskell eta +tags: parser +--- +Happy i Alex - biblioteki do budowania parserów dla języków Haskell i Eta. + diff --git a/_collections/_libs/hspec.html b/_collections/_libs/hspec.html new file mode 100644 index 00000000..0f156f6a --- /dev/null +++ b/_collections/_libs/hspec.html @@ -0,0 +1,14 @@ +--- +lib: hspec +title: HSpec +langs: haskell eta +tags: testing +--- +HSpec - biblioteki do pisania testów dla języków Haskell i Eta. + + + diff --git a/_collections/_libs/hunit.html b/_collections/_libs/hunit.html new file mode 100644 index 00000000..a5d6dcc9 --- /dev/null +++ b/_collections/_libs/hunit.html @@ -0,0 +1,14 @@ +--- +lib: hunit +title: HUnit +langs: haskell eta +tags: testing +--- +HUnit - biblioteki do pisania testów dla języków Haskell i Eta. + + + diff --git a/_collections/_libs/jackson.html b/_collections/_libs/jackson.html new file mode 100644 index 00000000..efc604f3 --- /dev/null +++ b/_collections/_libs/jackson.html @@ -0,0 +1,6 @@ +--- +lib: jackson +title: Jackson +langs: java +tags: json +--- diff --git a/_collections/_libs/jdbi.html b/_collections/_libs/jdbi.html new file mode 100644 index 00000000..e5147045 --- /dev/null +++ b/_collections/_libs/jdbi.html @@ -0,0 +1,6 @@ +--- +lib: jdbi +title: JDBI +langs: java +tags: sql +--- diff --git a/_collections/_libs/jolt.html b/_collections/_libs/jolt.html new file mode 100644 index 00000000..0b8092b4 --- /dev/null +++ b/_collections/_libs/jolt.html @@ -0,0 +1,6 @@ +--- +lib: jolt +title: Jolt +langs: java +tags: json +--- diff --git a/_collections/_libs/jool.html b/_collections/_libs/jool.html new file mode 100644 index 00000000..bd07f80c --- /dev/null +++ b/_collections/_libs/jool.html @@ -0,0 +1,6 @@ +--- +lib: jool +title: JOOL +langs: java +tags: fp +--- diff --git a/_collections/_libs/jooq.html b/_collections/_libs/jooq.html new file mode 100644 index 00000000..38049401 --- /dev/null +++ b/_collections/_libs/jooq.html @@ -0,0 +1,6 @@ +--- +lib: jooq +title: JOOQ +langs: java +tags: sql +--- diff --git a/_collections/_libs/jquery.html b/_collections/_libs/jquery.html new file mode 100644 index 00000000..5452ea13 --- /dev/null +++ b/_collections/_libs/jquery.html @@ -0,0 +1,6 @@ +--- +lib: jquery +langs: javascript +title: JQuery +--- +JQuery \ No newline at end of file diff --git a/_collections/_libs/jsonpath.html b/_collections/_libs/jsonpath.html new file mode 100644 index 00000000..814e2659 --- /dev/null +++ b/_collections/_libs/jsonpath.html @@ -0,0 +1,6 @@ +--- +lib: jsonpath +title: JsonPath +langs: java +tags: json +--- diff --git a/_collections/_libs/jsonsurfer.html b/_collections/_libs/jsonsurfer.html new file mode 100644 index 00000000..21815dc8 --- /dev/null +++ b/_collections/_libs/jsonsurfer.html @@ -0,0 +1,6 @@ +--- +lib: jsonsurfer +title: JsonSurfer +langs: java +tags: json +--- diff --git a/_collections/_libs/logback.html b/_collections/_libs/logback.html new file mode 100644 index 00000000..157626f6 --- /dev/null +++ b/_collections/_libs/logback.html @@ -0,0 +1,8 @@ +--- +lib: logback +title: Logback +langs: java +tags: logging +--- +Locback - biblioteka do logowania dla języków +Java, Kotlin i Scala. diff --git a/_collections/_libs/macwire.html b/_collections/_libs/macwire.html new file mode 100644 index 00000000..26b32d7a --- /dev/null +++ b/_collections/_libs/macwire.html @@ -0,0 +1,6 @@ +--- +lib: macwire +title: MacWire +langs: scala +tags: http +--- diff --git a/_collections/_libs/megaparsec.html b/_collections/_libs/megaparsec.html new file mode 100644 index 00000000..104e7b1a --- /dev/null +++ b/_collections/_libs/megaparsec.html @@ -0,0 +1,24 @@ +--- +lib: megaparsec +title: Megaparsec +langs: haskell eta +tags: parser +--- +MegaParsec - biblioteka do budowania parserów dla języków Haskell i Eta + diff --git a/_collections/_libs/optparse-applicative.html b/_collections/_libs/optparse-applicative.html new file mode 100644 index 00000000..526e6bb5 --- /dev/null +++ b/_collections/_libs/optparse-applicative.html @@ -0,0 +1,5 @@ +--- +lib: optparse-applicative +title: optparse-applicative +langs: haskell eta +--- diff --git a/_collections/_libs/parsec.html b/_collections/_libs/parsec.html new file mode 100644 index 00000000..86fb8383 --- /dev/null +++ b/_collections/_libs/parsec.html @@ -0,0 +1,12 @@ +--- +lib: parsec +title: Parsec +langs: haskell eta +tags: parser +--- +Parsec - biblioteka do budowania parserów dla języków Haskell i Eta + diff --git a/_collections/_libs/pulsar.html b/_collections/_libs/pulsar.html new file mode 100644 index 00000000..62629fac --- /dev/null +++ b/_collections/_libs/pulsar.html @@ -0,0 +1,9 @@ +--- +lib: pulsar +langs: clojure +title: Pulsar +--- +Pulsar - biblioteka dla języka Clojure, +która umożliwia programowanie z użyciem włókien (ang. fiber), +kanałów jak w języku Go +oraz aktoróœ w jak w języku Erlang. \ No newline at end of file diff --git a/_collections/_libs/quasar.html b/_collections/_libs/quasar.html new file mode 100644 index 00000000..e91226f8 --- /dev/null +++ b/_collections/_libs/quasar.html @@ -0,0 +1,9 @@ +--- +lib: quasar +langs: kotlin +title: Quasar +--- +Quasar - biblioteka dla języka Kotlin, +która umożliwia programowanie z użyciem włókien (ang. fiber), +kanałów jak w języku Go +oraz aktoróœ w jak w języku Erlang. diff --git a/_collections/_libs/quickcheck.html b/_collections/_libs/quickcheck.html new file mode 100644 index 00000000..be259061 --- /dev/null +++ b/_collections/_libs/quickcheck.html @@ -0,0 +1,12 @@ +--- +lib: quickcheck +title: QuickCheck +langs: haskell eta +tags: testing +--- +QuickCheck - biblioteki do pisania testów dla języków Haskell i Eta. + diff --git a/_collections/_libs/readp.html b/_collections/_libs/readp.html new file mode 100644 index 00000000..91323cd9 --- /dev/null +++ b/_collections/_libs/readp.html @@ -0,0 +1,27 @@ +--- +lib: readp +title: ReadP +langs: haskell eta +tags: parser +--- +ReadP - biblioteka do budowania parserów dla języków Haskell i Eta. + diff --git a/_collections/_libs/scala-guice.html b/_collections/_libs/scala-guice.html new file mode 100644 index 00000000..57659beb --- /dev/null +++ b/_collections/_libs/scala-guice.html @@ -0,0 +1,6 @@ +--- +lib: scala-guice +title: Scala Guice +langs: scala +tags: di +--- diff --git a/_collections/_libs/scala-optparse-applicative.html b/_collections/_libs/scala-optparse-applicative.html new file mode 100644 index 00000000..8d537819 --- /dev/null +++ b/_collections/_libs/scala-optparse-applicative.html @@ -0,0 +1,5 @@ +--- +lib: scala-optparse-applicative +title: scala-optparse-applicative +langs: scala +--- diff --git a/_collections/_libs/scalatest.html b/_collections/_libs/scalatest.html new file mode 100644 index 00000000..68dff4b2 --- /dev/null +++ b/_collections/_libs/scalatest.html @@ -0,0 +1,7 @@ +--- +lib: scalatest +title: ScalaTest +langs: scala +tags: testing +--- +ScalaTest to biblioteka do testów jednostkowych i akceptacyjnych dla języka Scala. diff --git a/_collections/_libs/scalatra.html b/_collections/_libs/scalatra.html new file mode 100644 index 00000000..94303ab1 --- /dev/null +++ b/_collections/_libs/scalatra.html @@ -0,0 +1,6 @@ +--- +lib: scalatra +title: Scalatra +langs: scala +tags: http +--- diff --git a/_collections/_libs/scalawui.html b/_collections/_libs/scalawui.html new file mode 100644 index 00000000..194fce38 --- /dev/null +++ b/_collections/_libs/scalawui.html @@ -0,0 +1,6 @@ +--- +lib: scalawui +title: ScalaWUI +langs: scala +tags: http +--- diff --git a/_collections/_libs/scalaz.html b/_collections/_libs/scalaz.html new file mode 100644 index 00000000..327eef70 --- /dev/null +++ b/_collections/_libs/scalaz.html @@ -0,0 +1,8 @@ +--- +lib: scalaz +title: Scalaz +langs: scala +tags: testing +--- +Scalaz - biblioteka dla języka Scala, +która umożliwia programowanie czysto-funkcyjne znane z języka Haskell. \ No newline at end of file diff --git a/_collections/_libs/shocon.html b/_collections/_libs/shocon.html new file mode 100644 index 00000000..c1545078 --- /dev/null +++ b/_collections/_libs/shocon.html @@ -0,0 +1,7 @@ +--- +lib: shocon +title: SHocon +langs: scala +tags: hocon +--- +SHocon diff --git a/_collections/_libs/slogging.html b/_collections/_libs/slogging.html new file mode 100644 index 00000000..a1c6cc54 --- /dev/null +++ b/_collections/_libs/slogging.html @@ -0,0 +1,7 @@ +--- +lib: slogging +title: slogging +langs: scala +tags: logging +--- +slogging to biblioteka do logowania dla języka Scala. diff --git a/_collections/_libs/specs2.html b/_collections/_libs/specs2.html new file mode 100644 index 00000000..e5067d98 --- /dev/null +++ b/_collections/_libs/specs2.html @@ -0,0 +1,7 @@ +--- +lib: specs2 +title: specs2 +langs: scala +tags: testing +--- +specs2 to biblioteka do testów jednostkowych i akceptacyjnych dla języka Scala. diff --git a/_collections/_libs/sqlite.html b/_collections/_libs/sqlite.html new file mode 100644 index 00000000..f693f66a --- /dev/null +++ b/_collections/_libs/sqlite.html @@ -0,0 +1,5 @@ +--- +lib: sqlite +title: SQLite +tags: database +--- diff --git a/_collections/_libs/stoml.html b/_collections/_libs/stoml.html new file mode 100644 index 00000000..eb5bcdcc --- /dev/null +++ b/_collections/_libs/stoml.html @@ -0,0 +1,8 @@ +--- +lib: stoml +title: STOML +langs: scala +tags: toml +--- +STOML +toml-scala diff --git a/_collections/_libs/trifecta.html b/_collections/_libs/trifecta.html new file mode 100644 index 00000000..1337dfd1 --- /dev/null +++ b/_collections/_libs/trifecta.html @@ -0,0 +1,15 @@ +--- +lib: trifecta +title: Trifecta +langs: haskell +tags: parser +--- +Trifecta - biblioteka do budowania parserów dla języka Haskell. + diff --git a/_collections/_libs/udash.html b/_collections/_libs/udash.html new file mode 100644 index 00000000..09115fb4 --- /dev/null +++ b/_collections/_libs/udash.html @@ -0,0 +1,6 @@ +--- +lib: udash +title: Udash +langs: scala +tags: http +--- diff --git a/_collections/_libs/utest.html b/_collections/_libs/utest.html new file mode 100644 index 00000000..29cc70c5 --- /dev/null +++ b/_collections/_libs/utest.html @@ -0,0 +1,7 @@ +--- +lib: utest +title: µTest +langs: scala +tags: testing +--- +utest to biblioteka do testów jednostkowych dla języka Scala. diff --git a/_collections/_libs/vavr-kotlin.html b/_collections/_libs/vavr-kotlin.html new file mode 100644 index 00000000..d91bcbad --- /dev/null +++ b/_collections/_libs/vavr-kotlin.html @@ -0,0 +1,10 @@ +--- +lib: vavr-kotlin +title: vavr-kotlin +langs: kotlin +tags: fp +--- +Vavr integration for Kotlin - biblioteka dla języka Kotlin, +która umożliwia programowanie funkcyjne znane z języków Scala i Ocaml. + +Twitter : @vavr_io \ No newline at end of file diff --git a/_collections/_libs/vavr.html b/_collections/_libs/vavr.html new file mode 100644 index 00000000..b8d76420 --- /dev/null +++ b/_collections/_libs/vavr.html @@ -0,0 +1,10 @@ +--- +lib: vavr +title: Vavr +langs: java +tags: fp +--- +Vavr - biblioteka dla języka Java, +która umożliwia programowanie funkcyjne znane z języków Scala i Ocaml. + +Twitter : @vavr_io \ No newline at end of file diff --git a/_collections/_libs/zio.html b/_collections/_libs/zio.html new file mode 100644 index 00000000..7f4fcc1d --- /dev/null +++ b/_collections/_libs/zio.html @@ -0,0 +1,10 @@ +--- +lib: zio +title: ZIO +langs: scala +tags: fp +--- +ZIO - biblioteka dla języka Scala, +która umożliwia programowanie z użyciem włókien (ang. fiber), +kanałów jak w języku Go +oraz lekkich aktorów w jak w języku Erlang. diff --git a/_collections/_microblog/jezyk-fullstackowy.md b/_collections/_microblog/jezyk-fullstackowy.md new file mode 100644 index 00000000..afca1b19 --- /dev/null +++ b/_collections/_microblog/jezyk-fullstackowy.md @@ -0,0 +1,115 @@ +W ciągu ostatnich 48h zarzucono mi to wiele rzeczy, ale nikt mi nie będzie zarzucać że nie wiem, że `nawet w WEB można się już obyć bez JS`, dlatego przeklejam tu swój stary artykuł z bloga. Mam nadzieję że przez rok się mocno nie zdezaktualizował. + +Nie jest to artykuł profesjonalisty, ale bardziej zapiski hobbysty i próba usystematyzowania nowych rzeczy. Proszę o konstruktywną krytykę. `Jesteś upośledzony` to nie jest konstruktywna krytyka, bo to już wiem (mam krótkowzroczność -8D, niezdiagnozowanego Aspergera i totalny brak gustu). BTW Podobno jest to najlepszy artykuł jaki mam na blogu, więc kolejne będą jeszcze gorsze :P + +Z pozdrowieniami dla frontendowców za to że piszą front i dzięki temu ja tego nie muszę robić. + +# Który język programowania wybrać na początek - język fullstackowy + +Wiele osób pyta się, **który język programowania wybrać na początek** jako pierwszy język do nauki. Wiele jednak zależy od tego do czego chcemy użyć tego języka programowania. Dlatego wybrałem zwycięzców w czterech kategoriach: +1. [dynamicznie typowany język skryptowy ogólnego przeznaczenia](https://www.writeonly.pl/programming/jezyk-skryptowy/) +2. [statycznie typowany język korporacyjny używany do pisania długowiecznych aplikacji klasy *enterprise*](https://www.writeonly.pl/programming/jezyk-korporacyjny/) +3. język *fullstackowy*, który można używać do pisania frontendu i backendu +4. [szybki język natywny działający bez maszyny wirtualnej i interpretera](https://www.writeonly.pl/programming/jezyk-natywny/) + +W tym artykule skupię się na zwycięzcy trzeciej kategorii, świętym Graalu programowania webowego, czyli języku *fullstackowy*, w którym można pisać zarówno frontend jak i backend. + +**Ważna uwaga!** +Artykuł nie jest sponsorowany przez Google, mimo że każdy ze zwycięskich języków jest używany przez Google. Nie jest też sponsorowany przez JetBrains. Po prostu uważam, że JetBrains tworzy najlepsze IDE. Jest to tylko mój mały subiektywny ranking języków programowania na rok 2019. + +## JavaScript oraz jego problemy i dziwactwa +**JavaScript** jest obecnie jedynym językiem programowania wspieranym przez przeglądarki bezpośrednio. Dlatego jesteśmy skazani na niego przy programowaniu frontendu działającego po stronie przeglądarki. Jednocześnie JS posiada sporo swoich problemów i dziwactw. Zaczynając od najważniejszych są to: +1. Różne implementacje w różnych przeglądarkach +2. Słabe typowanie, które pozwala robić takie rzeczy jak JSFuck +3. Obiektowość oparta na [prototypach](https://pl.wikipedia.org/wiki/Prototyp_(oprogramowanie)). + +Ostatnie nie byłoby nawet problemem gdyby nie to, że w początkowej fazie istnienia rozdziału na frontend i backend programiści backendowi byli przymuszani do pisania frontendu. Bolało to zwłaszcza programistów języków korporacyjnych, gdzie obiektowość oparta jest na [klasach](https://pl.wikipedia.org/wiki/Klasa_(programowanie_obiektowe)). + +### Podejście zerowe +Początkowo głównym problemem z JavaScryptem było to, że był różnie implementowany w różnych przeglądarkach. W niektórych przeglądarkach brakowało niektórych funkcji, w innych te same funkcje zachowywały się różnie. Spowodowało to powstawanie wielu różnych nakładek i bibliotek na JS, z czego jedna stała się *de facto* standardem - **JQuery**. Było to jednak w dawnych czasach, gdy programowanie JavaScripcie było proste, ponieważ służył on głownie do robienia bezsensownych animacji na strona oraz customowych menu kontekstowych. + +Obecnie głównym problemem pisania aplikacji webowych jest to, że potrzebujemy osobnych programistów do tworzenia frontendu (*frontendowców*) i osobnych do tworzenia backendu (*backendowców*). Teoretycznie istnieje święty Graal wszelakiej rekrutacji, człowiek orkiestra, Leonardo da Vinci swoich czasów, czyli fullstackowiec potrafiący pisać zarówno frontend jak i backend. W praktyce jest to jednak osoba znająca się na wszystkim, ale po trochu. Trochę jak np. internista w szpitalu. Rozwiązaniem jest dopiero język *fullstackowy*. + +### Podejście pierwsze - język backendowy transpilowany do JS + +Ponieważ programistów JavaScriptu było mało, a frontend stawał się coraz bardziej skomplikowany pojawił się pomysł, żeby już istniejące języki backendu transpilować do JS. Dzięki temu programiści backendu mogą z marszu stać się programistami frontendu. Tutaj są dwie grupy rozwiązań: +* Biblioteki graficzne przeniesione do **JS**: + * RAP (ang. *Remote Aplication Platform*) - to implementacja SWT (ang. *Standard Widget Toolkit*). SWT to niestandardowy (sic!) zestaw bibliotek graficznych dla Javy, posiadający implementacje dla najpopularniejszych systemów operacyjnych (Mac, Linux, Windows). +* GWT (ang. *Google Widget Toolkit*) - biblioteka graficzna zaprojektowana dla Javy specjalnie pod transpilację do JS + * Pyjs - Port GWT dla języka **Python** +* Język backendu przeniesiony do frontendu jednocześnie nie narzucający frameworka widoku i biblioteki graficznej: + * **Scala.js** - posiada już dedykowane frameworki ja *Udash* + * Kotlin.js - dalej w procesie projektowania + * Ceylon.js - transpilowany do CommonJS + * ClojureScript* - używa Closure Compiler do optymalizacji kodu. Tutaj pojawia się gwiazdka ponieważ istnieją [różnice](https://clojurescript.org/about/differences) pomiędzy +**Clojure** i ClojureScript + * Dla Javy: + * J2CL - transpilator od Google używający Closure Compiler i będący następcą GWT + * JSweet - transpilator do języka **TypeScript**, który następnie jest transpilowany do JS + * Programiści języka **Haskell** także podejmowali kilka prób stworzenia transpilatora z Haskella do JS. Są to Fay, GHCJS, Haste i uhc + * Dla języka **OCaml** jest kilka transpilatorów, ale aktualnie najbardziej obiecująco wygląda **BuckleScript.** + * Język **Racket** był jednym z pierwszych transpilowanych do JS, aktualnie jest rozwijany RacketScript + +### Podejście drugie - nowy język transpilowany do JS + +Według wielu programistów pierwsze podejście było niezadowalające. Istniało wiele problemów z językami backedowymi transpilowanymi do JS. Prawdopodobnie największym jest przetwarzanie współbieżne. Statycznie typowane języki korporacyjne posiadają wielowątkowość do przetwarzania współbieżnego. Interpretery JS posiadają jeden wątek i do przetwarzania współbieżnego używa konstrukcji `Promise` (*obietnicy*), której najbliżej do monady) `IO` z Haskella lub FlatMappable `Future` ze Scali. Ponieważ nie da się łatwo zamienić modelu `Promise` na wielowątkowość to jest to problemem. + +Ponieważ pierwsze podejście okazało się niezadowalające postanowiono stworzyć nowe języki programowania będące jak najbardziej podobne do JS, ale jednocześnie rozwiązujące znane w nim problemy. Te języki to m.in.: +* **CoffeeScript** - pierwszy popularny, nowy język transpilowany do JS. Posiada klasy i *normalne* dziedziczenie, ale typowany dynamicznie. Promowany przez programistów **Ruby** we frameworku RoR +* **LiveScript** - funkcyjny następca CoffeeScriptu +* **TypeScript** - rozszeżenie **JS** o statyczne typowanie i klasy +* **PureScript** - **Haskell**, ale wykonywany zachłannie, czyli jak *normalny* język programowania, a nie Haskell +* **ReasonML** - **OCaml** ze zmienioną składnią w celu upodobnienia go do **JS**. Także transpilowany za pomocą **BuckleScript**. +* **Elm** * - język będący połączeniem języków **Meta Language** i **Haskell** oraz będący już zintegrowany z frameworkami React i Redux (implementacja architektury Flux). Jest z gwiazdką, bo jest dedykowany tylko do pisania frontendu. Jednocześnie posiada ciekawą właściwość jaką jest usuwanie martwego kodu podczas transpilacji. Dlatego aplikacja napisana w Elmie może być mniejsza niż kod Reacta +* **Dart** * - kolejny język z gwiazdką. Mimo że jest względnie młody przeszedł już historię dzielącą się na etapy: + 1. Natywny język przeglądarki - niestety wykonywany natywnie tylko przez Chroma. Inne przeglądarki miały posiadać maszynę wirtualną Darta napisaną w JS. + 2. Język do pisania frontendu, transpilowany do JS + 3. Język do pisania frontendu i aplikacji mobilnych za pomocą frameworku Flutter + +Ale jakim cudem w ogóle można mówić o JS jako o języku *fullstackowym*? Spójrzy na małe kalendarium: +* 2007 - Qt dodaje Qt Script, własną implementacją EmcaScriptu, język jest dedykowany do tworzenia **GUI**. Teoretycznie nic to nie wnosi do tej historii, ale zainspirowało niektórych +* 2008 - Gnome dodaje dwa [bindingi Javascriptu](https://wiki.gnome.org/JavaScript), Gjs i Seed. Są one dedykowane do tworzenia **GUI** w miejsce wcześniej stosowanego w tym celu języka **Python**, ale można ich używać jako główny język do pisania aplikacji oraz jako język skryptowy +* 2009 - powstaje Node.js, wyciągnięty z przeglądarki interpreter] V8, który można używać z linii poleceń CLI +* 2011 - powstaje Vert.x, framework do przetwarzania współbieżnego na JVM, który posiada API m.in. w JavaScripcie + +A więc wszystkie języki transpilowane do JS (i sam JS oczywiście) można wykonywać po stronie backendu! +### Podejście wygrywające +zwycięzcą kategorii *język fullstackowy* jest język transpilowany do JS i jest to ... JavaScript! + +Co?! Dlaczego JavaScript jest transpilowany do JavaScriptu? Wynika to z tego, że w międzyczasie tworzenia gigantycznej ilości nakładek do JavaScriptu sam Javascript też był rozwijany. Niestety dalej trzeba wspierać stare przeglądarki używające starszych wersji JavaScriptu. Dlatego jest potrzebny transpilator Babel zamieniający ECMAScript 6 do ECMAScript 5. + +A dlaczego JavaScript jest zwycięzcą? +* Ewoluował i nie jest już tak brzydki jak kiedyś +* Jest popularny - język roku 2014 według Tiobe +* Nawet jeśli będziesz pisać frontend w innym języku programowania niż JS to prawdopodobnie i tak będziesz musiał znać podstawy JavaScriptu, +* Niestety [WebStorm] od JetBains jest płatny, ale na szczęście istnieją inne dobre IDE dla JavaScriptu jak Atom lub VSC. +* Chyba wreszcie zrozumieli JS w Google. Google długo miało problemy z JavaScriptem i dlatego m.in. stworzyło GWT. Jednak od pewnego czasu Google wspiera użycie JavaScriptu np w Google Cloud Functions, gdzie można używać tylko i wyłącznie JavaScriptu. + +Ale nie to jest największą zaletą JavaScriptu! Największą zaletą jest Node.js. A największą zaletą Node.js jest to, że jest jednowątkowy i zmusza do pisania aplikacji funkcyjnych, asynchronicznych i reaktywnych + +Node.js nie jest jedynym asynchronicznym serwerem. Istnieją także inne jak: +* Vert.x - wielki framework dla języków JavaScript, Java, Scala, Kotlin, **Ceylon**, Groovy i **Ruby** +* Lagom - kolejny wielki framework, dedykowany dla języka Java +* Akka HTTP - biblioteka dedykowana dla języków **Scala** i Java +* Spark - biblioteka dedykowana dla języków **Kotlin** i Java +* Ratpack - biblioteka dedykowana dla języków Groovy i Java +* WebFlux - reaktywa wersja Springa + +Wiele innych frameworków także zaczyna wspierać programowanie asynchroniczne, jak np. DropWizard. +## Podsumowanie + +Trudno tutaj o dobre podsumowanie. Chyba nie mam odwagi polecić komuś JavaScript/TypeScript do nauki jako pierwszy język do programowania. +Głównie obawiając się o zdrowie psychiczne tej osoby, która miałaby programować w JS. + +Osobiście jestem zwolennikiem statycznie typowanych języków backendu transpilowanych do JS, jak np. Scala.js lub Kotlin.js. Pozwala to współdzielić kod między frontendem i backendem, który teoretycznie może być nawet aplikacją natywną. Jednocześnie w tych językach programowania do rozwiązywania problemów asynchroniczności są preferowane konstrukcje `Future` oraz **monady** `IO`, które łatwo przetłumaczyć na `Promise` z JS. + +Równie ciekawy wydaje się także, pojawiącący w niektórych zagranicznych ogłoszeniach o pracę, stos technologiczny PHP, czyli: +* **P**ureScript na frontendzie +* **H**askell na backandzie +* **P**ostgreSQL jako baza danych + +Są to co prawda dwa języki programowania do nauki, ale bardzo podobne do siebie. O wiele bardziej niż Java i JavaScript. Więc opanowanie jednego z nich, gdy umie się już drugi nie powinno być problemem. + +[Link do oryginalnego artykułu](https://www.writeonly.pl/programming/jezyk-fullstackowy/) + +#writeonly diff --git a/_collections/_posts/2018-08-13-dlaczego-warto-prowadzic-bloga.md b/_collections/_posts/2018-08-13-dlaczego-warto-prowadzic-bloga.md new file mode 100644 index 00000000..635837ba --- /dev/null +++ b/_collections/_posts/2018-08-13-dlaczego-warto-prowadzic-bloga.md @@ -0,0 +1,66 @@ +--- +title: "Dlaczego warto prowadzić bloga o programowaniu" +author: TheKamilAdam +category: thoughts +tags: blog +langs: scala java +tools: github +libs: +redirect_from: + - dlaczego-warto-prowadzic-bloga + - thoughts/dlaczego-warto-prowadzic-bloga + - thoughts/2018/08/13/dlaczego-warto-prowadzic-bloga.html +--- + +Ja znalazłem cztery powody, dlaczego warto prowadzić bloga o programowaniu. +Natrafiałem na nie właśnie w tej kolejności. + +## Notatki dla siebie +Nie wiem jak inni programiści, +ale ja mam dobrą pamięć do rzeczy złożonych, +jak np. składnia języka **[Scala]**, +i słabą pamięć do rzeczy prostych, jak np. “z jakimi parametrami należy budować projekt w języku Scala, żeby otrzymać żądany efekt”. +Rezultat tego był taki, że wielokrotnie przeszukiwałem internet w poszukiwaniu tych samych rzeczy. +Pierwszą próbą rozwiązania mojego problemu był pomysł zapisywania wiedzy w pliku na dysku. +Niestety po formacie dysku ta wiedza się traciła. +Kolejnym krokiem było trzymanie wiedzy w chmurze np. w Dokumentach Googlowych. + +## Pomoc dla innych +Nie tylko ja mam słabą pamięć. +Poza tym do pracy przychodzą też nowi lub ludzie z innych zespołów, którzy chcą się czegoś dowiedzieć. +Głupio mi było odpowiedzieć, że czegoś nie pamiętam, gdy wiedzą że robię to od roku.q +Wycinanie fragmentów Dokumentów Googlowych i wysyłanie ich przez komunikator nie było najbardziej eleganckim rozwiązaniem. +Więc założyłem repozytorium na **[GitHubie]** i odsyłałem linki jako odpowiedzi na pytania. +Było to rozwiązanie lepsze, ale nie zadowalało mnie w pełni, +ponieważ w ten sposób mogłem pomóc tylko osobom, które mnie bezpośrednio poprosiły o pomoc. + +## Dokumentowanie swojego postępu prac + +Repozytoria na GitHubie, bez dodatkowej dokumentacji szybko mogą przerodzić się w chaos. +Tak było zarówno w przypadku mojego repozytorium zawierającego wiedzę, jak i moich projektów Scalowych. +Blog będący Dziennikiem Postępów Prac pozwala temu przeciwdziałać i zaprezentować innym zastosowane rozwiązania. + +## Dostanie wymarzonej pracy +Jest to ostatni powód, który odkryłem. Jest to także powód, który ostatecznie zmotywował mnie do założenia tego bloga. + +Jestem programistą **[Javy]**, a chcę być programistą **[Scali]**. +Fascynuję się tym językiem programowania odkąd o nim usłyszałem, czyli dłużej niż pracuję w Javie. +Niestety na Górnym Śląsku, gdzie mieszkam, jest mało pracy dla programistów Scali. +Można pracować zdalnie, ale jest ciężko przekonać firmy programistyczne, +że umie się Scalę, gdy pisało się w niej komercyjnie tylko pół roku. + +Mimo że hobbistycznie piszę w niej od pięciu lat. + +## Podsumowanie +Mój plan jest taki, +żeby umieszczać tu posty głównie związane z postępem prac nad moimi projektami opensoursowymi pisanymi dla wprawy. +Dokumentować tutaj każdą większą zmianę wraz z uzasadnieniem. + +Mam nadzieję, że będzie to jasne i łatwe do zrozumienia zarówno dla mnie, gdy po roku wrócę do swojego kodu, +jak i dla wszystkich innych, którzy chcieliby się nauczyć języka **[Scala]**. + +[Javy]: /langs/java +[Scala]: /langs/scala +[Scali]: /langs/scala + +[GitHubie]: /tools/github diff --git a/_collections/_posts/2018-08-22-jekyll-i-ciasteczka-pliki-cookies.md b/_collections/_posts/2018-08-22-jekyll-i-ciasteczka-pliki-cookies.md new file mode 100644 index 00000000..2cfc0217 --- /dev/null +++ b/_collections/_posts/2018-08-22-jekyll-i-ciasteczka-pliki-cookies.md @@ -0,0 +1,108 @@ +--- +title: "Jekyll i ciasteczka (pliki cookies)" +author: TheKamilAdam +category: jekyll +tags: blog html jekyllcodex github-pages +labels: cookies +tools: jekyll +libs: jquery +redirect_from: + - jekyll-i-ciasteczka-pliki-cookies + - jekyll/jekyll-i-ciasteczka-pliki-cookies + - writeonlydoc/jekyll-i-ciasteczka-pliki-cookies + - writeonlydoc/2018/08/22/jekyll-i-ciasteczka-pliki-cookies.html +--- + +Przed założeniem bloga opartego na technologiach **[Jekyll]** i **[GitHub Pages]** +przejrzałem sporo polskojęzycznych blogów z opisem “Jak to zrobić”. +Wszyscy mówili, że jest to niesamowicie proste. +Za wyjątkiem jednego malkontenta, Gutka (). + +Pierwszy wieczór spędziłem na nieudanej instalacji Jekylla i próbie uruchomienia przykładowego bloga opartego na motywie graficznym BlackDocs +(). +Wieczór zakończyłem w momencie przeczytania porady na StackOverflow “usuń Rubiego i zainstaluj wszystko ponownie”. +Wtedy stwierdziłem, że może jednak Gutek ma rację i Jekyll bywa problematyczny. + +Jednak nie poddałem się i po paru wieczorach miałem pusty blog z możliwością komentowania postów i skryptem raportującym statystyki +(funkcjonalność dodana według ) +oraz nie do końca skonfigurowaną wyszukiwarką (). +W tym momencie uznałem, że dalsze usprawnianie bloga, który nie zawiera żadnej treści, nie ma żadnego sensu. +W związku z czym odłożyłem na czas późniejszy dodawanie tagów i kategorii “bez użycia pluginu” +( i ). +A nuż w międzyczasie plugin dla kategorii znajdzie się na liście pluginów wspieranych przez **[GitHub Pages]** +(Aktualna lista wspieranych pluginów ). + +Po opublikowaniu pierwszego posta czułem jednak, że dalej czegoś brakuje. Wciśnięcie F12 i spojrzenie w kod strony było przerażające. +Ujrzałem spaghetti w postaci naprzemiennie występujących fragmentów HTML, CSS i JS. +Ale najgorsze było, gdy spojrzałem na zakładkę “Storage”. +Okazało się, że moja prosta strona internetowa zapisuje, o zgrozo, ciasteczka. +O ile ciasteczko dla systemu komentarzy Disqus można jeszcze obronić, że jest technicznie potrzebne do działania funkcjonalności, +o tyle ciasteczko dla Google Analytics jest już jawnym śledzeniem użytkownika! + +Poszukiwanie rozwiązania mojego problemu doprowadziło mnie do strony , +a dokładniej do sekcji “Without plugins” (). +Znalazłem tam skrypt wyświetlający banner informujący o plikach Cookies. Po moich przeróbkach wygląda on tak: + +```html + + + + +``` + +Czuję, że na stronie spędzę więcej czasu z czego wynikają dwie smutne informacje: +* później zacznę pisać o języku **[Scala]** +* istnieje niebezpieczeństwo, że nauczę się jQuery + +[Scala]: /langs/scala + +[Jekyll]: /tools/jekyll + +[GitHub Pages]: /tags/github-pages diff --git a/_collections/_posts/2018-08-30-alias-komenda-powloki-bash.md b/_collections/_posts/2018-08-30-alias-komenda-powloki-bash.md new file mode 100644 index 00000000..0831ac76 --- /dev/null +++ b/_collections/_posts/2018-08-30-alias-komenda-powloki-bash.md @@ -0,0 +1,105 @@ +--- +title: "Alias - polecenie powłoki Bash" +author: TheKamilAdam +category: cli +tags: alias cli +tools: bash git +redirect_from: + - alias-komenda-powloki-bash + - cli/alias-komenda-powloki-bash + - cli/2018/08/30/alias-komenda-powloki-bash.html +--- + +Jeśli: +* masz problemy z zapamiętywaniem skomplikowanych poleceń Basha lub innych programów wywoływanych przez wiersz poleceń +* nie lubisz wpisywać w terminalu długich poleceń z podkomendami i przełącznikami + +istnieje rozwiązanie twoich problemów! Jest to polecenie powłoki Bash o nazwie `alias`. + +Polecenie `alias` można wywołać bez żadnego parametru: +```bash +alias +``` + +wyświetli wtedy listę wszystkich zdefiniowanych aliasów dostępnych w danym terminalu. + +## Tworzenie aliasów + +Żeby utworzyć nowy alias należy wywołać: +```bash +alias NAME=VALUE +``` + +gdzie: +* `NAME` oznacza nazwę nowego "polecenia" do wywoływania w wierszu poleceń +* `VALUE` jest poleceniem, lub ciągiem poleceń, które zostanie wywołana naprawdę. +Jeśli chcemy, żeby `VALUE` zawierało spację należy wszystko umieścić w parze apostrofów (') lub cudzysłowów (") + +Przykłady użycia: +```bash +alias rf='fm -rf' +alias ..='cd ..' +alias cwd='cd `pwd`' +``` +Od teraz : +* polecenie `rf <ścieżka_do_folderu>` będzie usuwać foldery, +* polecenie `..` przechodzić do folderu wyżej w drzewie hierarchii folderów, +* polecenie `cwd` będzie odświeżać aktywny folder. + +## Tworzenie permanentnych aliasów +Problem z aliasami jest tylko jeden. Działają tylko w ramach terminala w którym zostały zdefiniowane. +Można to rozwiązać w prosty sposób poprzez stworzenie wszystkich aliasów w pliku, np. pod nazwą `~/.bash_aliases`, +a następnie wczytywania go za pomocą polecenia `source`. +Teraz po otwarciu nowego terminala wystarczy wywołać: +```bash +source ~/.bash_aliases +``` + +by cieszyć się swoimi aliasami w każdym terminalu. + +## Automatyczne wczytywanie aliasów +Można to jednak jeszcze bardziej uprościć. +Przy starcie każdego nowego terminala jest wczytywany plik `~/.bashrc`. +Wystarczy na końcu tego pliku dodać: +```bash +source ~/.bash_aliases +``` +lub bezpieczniej: +```bash +if [ -f ~/.bash_aliases ]; then + . ~/.bash_aliases +fi +``` +Dodatkowy `if` uchroni nas przed błędem, gdy plik `~/.bash_aliases` nie istnieje. +Kropka na początku drugiej linii jest aliasem na `source`. + +Dodatkowo do pliku `~/.bash_aliases` warto dodać aliasy: +```bash +alias vish='vim ~/.bashrc' +alias srcsh='source ~/.bashrc' +``` + +## Niezniszczalne aliasy +Używanie aliasów nie jest niczym nowym. +Możliwe, że w waszej dystrybucji będzie już istnieć plik `~/.bash_aliases` czekający na uzupełnienie +lub nawet będzie już wczytywany w pliku `~/.bashrc`. +Także cała powyższa procedura jest opisana na wielu stronach i blogach. + +Mój główny problem z aliasami polegał na tym, +że gdy już miałem uzbierany pokaźny zestaw aliasów ułatwiających mi życie padł mi dysk w służbowym laptopie. +Komputer poszedł do działu IT, wymienili mi dysk, ale ja straciłem wszystkie aliasy. + +Stwierdziłem wtedy "Moja wina, bo wszystko, co tylko można, należy trzymać w chmurze". +Więc założyłem repozytorium na githubie [cli](https://github.com/writeonly/cli), +gdzie w pliku [bash_aliases](https://github.com/writeonly/cli/blob/master/bash_aliases) ponownie zbieram potrzebne mi aliasy. +Dodatkowo zrobiłem mały skrypt instalujący, tak by jedną linią +```bash +wget https://raw.githubusercontent.com/writeonly/cli/master/bash_aliases_install.sh | bash +``` +móc odzyskać wszystko to, do czego przywykłem. + +A polecenie: +```bash +update_aliases +``` +można zaktualizować aliasy. \ No newline at end of file diff --git a/_collections/_posts/2018-09-05-docker-usuwanie-obrazow.md b/_collections/_posts/2018-09-05-docker-usuwanie-obrazow.md new file mode 100644 index 00000000..3de1475d --- /dev/null +++ b/_collections/_posts/2018-09-05-docker-usuwanie-obrazow.md @@ -0,0 +1,56 @@ +--- +title: "Docker - usuwanie obrazów" +author: TheKamilAdam +category: cli +tags: alias cli +tools: docker +redirect_from: + - docker-usuwanie-obrazow + - cli/docker-usuwanie-obrazow + - cli/2018/09/05/docker-usuwanie-obrazow.html +--- + +Dziesięć lat pracy na Linuksie nauczyło mnie, +że jeśli Linuks zaczyna magicznie i bez ostrzeżenia sam z siebie nie działać +to najprawdopodobniej skończyło się miejsce na dysku. +Identycznie jest z Dockerem. +Jeśli lokalnie stawiamy chmurę mikroserwisów, +które często pojawiają się w nowych wersjach, +to prędzej czy później zabraknie nam miejsca na dysku. +W skrajnym wypadku, na laptopie zastępczym, musiałem dwa razy w tygodniu usuwać obrazy Dockerowe. + +## Procedura usuwania obrazów Dockerowych +Szczęśliwie procedura usuwania obrazów Dockerowcyh nie jest czynnością skomplikowaną i składa się z trzech kroków. +Na początek włączamy terminal i teraz kolejno wykonujemy kroki: + +Krok 1. Zatrzymujemy wszystkie kontenery: +```bash +docker kill $(docker ps -q) +``` + +Krok 2. Usuwamy wszystkie kontenery: +```bash +docker rm $(docker ps -a -q) +``` + +Krok 3. Usuwamy wszystkie obrazy: +```bash +docker rmi $(docker images -q) +``` + +## Wszystko razem +Można także wykonać wszystko razem jako jedno, połączone polecenie w terminalu: + +```bash +docker kill $(docker ps -q); docker rm $(docker ps -a -q); docker rmi $(docker images -q) +``` + +Lepiej jest jednak dodać wpis do pliku `~/.bash_aliases` : +```bash +alias docker_rmi_all='docker kill $(docker ps -q); docker rm $(docker ps -a -q); docker rmi $(docker images -q)' +``` + +I wtedy wystarczy z wywołać w terminalu: +```bash +docker_rmi_all +``` diff --git a/_collections/_posts/2018-09-12-git-submoduly-i-aliasy.md b/_collections/_posts/2018-09-12-git-submoduly-i-aliasy.md new file mode 100644 index 00000000..3c2fdf96 --- /dev/null +++ b/_collections/_posts/2018-09-12-git-submoduly-i-aliasy.md @@ -0,0 +1,124 @@ +--- +title: "Git - submoduły i aliasy" +author: TheKamilAdam +category: cli +tags: cli alias interpreter +labels: submodule +langs: java javascript +tools: git +redirect_from: + - git-submoduly-i-aliasy + - cli/git-submoduly-i-aliasy + - cli/2018/09/12/git-submoduly-i-aliasy.html +--- + +*Post oparty na prawdziwych wydarzeniach i traumach* + +## Submoduły + +Zrobili to! +Mimo że protestowałem. +Do projektu przy którym pracowałem dodali submoduły. + +- Jak mogli to zrobić - zadaje pytanie oburzony. +- Prosto - pada odpowiedź - za pomocą polecenia o składni: +```bash +git submodule add link-do-repozytorium opcjonalna-nazwa-folderu +``` +A w tym wypadku było to dokładnie: +```bash +git submodule add https://github.com/paulp/sbt-extras.git sbtx +``` +wykonane w folderze projektu. + +- Ale po co? - drążę dalej temat. +- Żeby współdzielić kod. +- Przecież do tego służą biblioteki! - moje oburzenie sięga zenitu. +- Ale nie zawsze jest to łatwe i możliwe: + 1. Biblioteki trzeba wydawać i trzymać je w menedżerze repozytoriów binarnych (ang. *Binary Repository Manager*), +a takiego menedżera trzeba gdzieś zainstalować. + 2. Menedżer repozytorium binarnych może kosztować, np. dla języka **[Java]** jest za darmo, a dla języka **[JavaScript]** już niekoniecznie. + 3. W językach skryptowych biblioteki są często instalowane do **[interpretera]** + co może utrudniać instalację programu klientowi +(przykład z pierwszej wersji [Git-Tools-Submodules]()). + 4. Nie wszystko da się umieścić w bibliotece, w tym wypadku jest to skrypt do budowania projektu. + +## Dodatkowe polecenia +Tak przekonany przestałem marudzić + i przejrzałem [Git-Tools-Submodules](), + [git-submodule]() + oraz [git-clone](). + Okazało się, że praca z submodułami nie jest taka straszna i sprowadza się głównie do dwóch poleceń: + +```bash +git clone --recurse-submodules +git submodule update --init --recursive +``` +Pierwsze polecenie ściąga repozytorium ze wszystkimi submodułami. +Drugie - aktualizuje submoduły po przełączeniu się na inną rewizję (ang. *commit*), gałąź lub po aktualizacji gałęzi. + +Niestety polecenia te wydłużają i tak długie już polecenia gita. + +## Aliasy Basha + +Szczęśliwie umiem rozwiązywać problem długich poleceń, +bo znam [aliasy basha](/alias-komenda-powloki-bash). + +Pierwsza wersja moich aliasów wyglądała następująco: +```bash +alias g='git' +alias gcl='git clone' +alias gclr='gcl --recurse-submodules' +alias gupdate='git submodule update --init --recursive' +alias gpr='git pull --rebase' +alias gpru='gpr && gupdate' +alias master='git checkout master && gupdate' +alias develop='git checkout develop && gupdate' +``` + +## Aliasy Gita + +Byłem bardzo zadowolony ze swoich aliasów, więc postanowiłem się nimi pochwalić koledze: +- To bez sensu - odpowiedział zdziwiony - +przecież git ma swój system [aliasów](). + +Po przeczytaniu [Git-Basics-Git-Aliases]() +i [git-config]() +mój zbiór aliasów zamienił się w zestaw poleceń gita do wykonania: + +```bash +git config --global alias.cl 'clone' +git config --global alias.clr 'cl --recurse-submodules' +git config --global alias.update 'submodule update --init --recursive' +git config --global alias.pr 'pull --rebase' +git config --global alias.pru '!git pr && git update' +git config --global alias.master '!git checkout master && git update' +git config --global alias.develop '!git checkout develop && git update' +git config --global alias.tig '!tig' +``` +Widać tutaj, że podkomenda `alias` ma dwie składnie: +```bash +git config --global alias.nowa_komenda_gita 'stara_komenda_gita_z_parametrami' +git config --global alias.nowa_komenda_gita '!dowolna_komenda_basha' +``` + +I od teraz: +* `git cl` - klonuje repozytorium; +* `git clr` - klonuje repozytorium razem z submodułami; +* `git update` - aktualizuje submoduły; +* `git pr` - pobiera zmiany ze zdalnego repozytorium; +* `git pru` - pobiera zmiany ze zdalnego repozytorium i aktualizuje submoduły; +* `git master` - przełącza na gałąź master i aktualizuje submoduły; +* `git develop` - przełącza na gałąź develop i aktualizuje submoduły; +* `git tig` - uruchamia program `tig` (o ile mamy go zainstalowany). + +Polecenia te zapisałem w pliku [git_config.sh]() +i można je wykonać poleceniem: +```bash +curl -s https://raw.githubusercontent.com/writeonly/cli/master/git_config.sh | bash +``` + +[Java]: /langs/java +[JavaScript]: /langs/javascript + +[interpretera]: /tags/interpreter diff --git a/_collections/_posts/2018-09-26-jekyllcodex-org-czesc-druga.md b/_collections/_posts/2018-09-26-jekyllcodex-org-czesc-druga.md new file mode 100644 index 00000000..9dcb051d --- /dev/null +++ b/_collections/_posts/2018-09-26-jekyllcodex-org-czesc-druga.md @@ -0,0 +1,55 @@ +--- +title: "jekyllcodex.org - część druga" +author: TheKamilAdam +category: jekyll +tags: blog jekyllcodex seo +tools: jekyll +redirect_from: + - jekyllcodex-org-czesc-druga + - jekyll/jekyllcodex-org-czesc-druga + - writeonlydoc/jekyllcodex-org-czesc-druga + - writeonlydoc/2018/09/26/jekyllcodex-org-czesc-druga.html +--- + +Ponad miesiąc temu, w panice, szukałem prostego skryptu, który by wyświetlał ostrzeżenie o plikach cookies. +Skrypt odnalazłem na stronie [jekyllcodex.org](). +Strona ta zawiera repozytorium skryptów, które rozszerzają możliwości generatora statycznych stron Jekyll. + +Dziś już na spokojnie postanowiłem przejrzeć to repozytorium skryptów. +Przeszukiwanie prowadziłem pod kątem możliwości rozszerzenia funkcjonalności mojego bloga. + +## Skrypty, które użyłem +Skrypty wykorzystane przeze mnie podzieliłem na trzy kategorie ze względu na miejsce dodania skryptu: + +### Skrypty ogólne +Są to skrypty, które w większości trafiły do układu strony `default.html`: + +- [ostrzeżenie o plikach cookies]() +- [seo]() +- [kanał rss]() +- [przyciski linkujące do kont na portalach społecznościowych]() +- [czat na żywo]() - jeszcze nie wiem po co, ale dodałem. + +### Skrypty dla postów +Są to skrypty, które trafiły do układu strony `post.html`: + +- [wskaźnik czasu czytania]() +- [przyciski udostępniania dla mediów społecznościowych]() + +### Skrypty dla stron +Jest to w zasadzie jeden skrypt, który trafił do układu strony `page.html`: + +- [okruszki chleba]() - dla bloga nie za bardzo nie ma sens, +wydaje się przydatny tylko dla stron o zagnieżdżonej hierarchii + +## Skrypty, których jeszcze nie użyłem +Niestety nie zdążyłem wypróbować wszystkich skryptów, które mnie ciekawią i które mogłyby być użyteczne na blogu. +Te które pozostały do przetestowania dzielą się na dwie kategorie: + +### Skrypty robiące jakąś magię z menu +- [proste menu]() +- [mobilne menu]() + +### Skrypty dodające wyszukiwarki +- wyszukiwarka oparta o [google]() +- wyszukiwarka oparta o [skrypt lunar]() diff --git a/_collections/_posts/2018-10-03-przenosna-scala.md b/_collections/_posts/2018-10-03-przenosna-scala.md new file mode 100644 index 00000000..588602ad --- /dev/null +++ b/_collections/_posts/2018-10-03-przenosna-scala.md @@ -0,0 +1,149 @@ +--- +title: "Przenośna Scala" +author: TheKamilAdam +category: scala-native +tags: compiler native nojvm transpiler +langs: crystal erlang haskell go javascript pony rust scala +tools: clang jvm llvm node-js sbt scala-jvm scala-js scala-native +libs: akka +redirect_from: + - przenosna-scala + - scala-native/przenosna-scala + - resentiment/przenosna-scala + - resentiment/2018/10/03/przenosna-scala.html +--- + +Znajomy zajarał się językiem **[Rust]**. +Opowiada mi jaki to wspaniały język i pokazuje przykłady kodu. +**[Rust]** na pierwszy rzut oka wygląda jak skrzyżowanie **[C]** i języka **[Haskell]** plus kanały jak w języka **[Go]**. +Czyni go to pretendentem do bycia najbardziej skomplikowanym językiem programowania na świecie. +Pretendentem, bo istnieje wśród programistów JVM opinia, że najbardziej skomlikowanym językiem na świecie jest **[Scala]**. +**[Scala]** jest skrzyżowaniem Javy i Haskella plus aktory z języka **[Erlang]**. + +Przykłady kodu coś mi przypominają. +Wyglądają prawie jak w Scali tylko trochę mniej obiektowe, więc pytam: +- Dlaczego nie Scala? Jest to w tej chwili jedyny funkcyjny język programowania, który odniósł sukces komercyjny. +Nie licząc niszowego Erlanga - dodaję. +- Bo ja nie lubię **[JVM]** - odpowiada. - Za dużo musiałem robić w apletach. + +Po tej rozmowie zacząłem się zastanawiać czy istnieje możliwość używania Scali poza JVM. +Czy Scala jest językiem przenaszalnym na inne platformy? + +## Portable Scala - dwa razy tak i jeden raz nie + +### .Net Framework +Podobno największą konkurencją dla JVM jest .Net. + +Z kilka lat temu, jak o Scali zaczynano dopiero mówić, podobno ruszyły prace nad przeniesieniem Scali na .Net. +Podobno nawet M$ dofinansował ten projekt. + +Jednak do dziś nie ma języka Scala.NET ani S#. +Podobno różnice między JVM a .Net są zbyt duże, +żeby w sensowny sposób udało się przenieść statycznie typowany język programowania +z jednego środowiska uruchomieniowego na drugie. + +Podobno istniał jeden statycznie typowany język programowania, +który działał na obu platformach. +Jednak było to zalane taką ilością warstw abstrakcyjnych, +że czyniło go to bezużytecznym. + +### JavaScript +**[JavaScript]** jest platformą docelową dla każdego, +kto chce uruchamiać cokolwiek na stronie internetowej. +Dlatego jeśliby posiadać **[transpilator]** Scali do JavaScriptu +to w łatwy sposób można by z każdego programisty Scali stworzyć legendarnego Full-Stack Developera. +Szczęśliwie taki **[transpilator]** istnieje i nazywa się **[Scala.js]**. +Istnieje nawet [Akka.js], framework aktorów. + +Niestety **[Scala.js]** i Akka.js posiadają wszystkie wady **[Node.js]** to znaczy jednowątkowość, +ale do front-endu wydają się idealne. + +### Native +Największą zaletą języków +**[Rust]**, **[Pony]**, **[Crystal]** czy **[Go]**, +jest to, +że są to języki kompilowane do postaci natywnej, +a programy w nich pisane mogą być dostarczane do klienta pod postacią jednego pliku. + +To samo ze Scalą robi **[kompilator]** **[Scala Native]** oparty na **[LLVM]**. +Niestety dalej jest w wersji eksperymentalnej i nie posiada np. wielowątkowości. +Co czyni go na razie tylko zabawką dla nerdów i np. ... DevOpsów oraz QA. +Bo o ile jednowątkowy program na produkcji zwykle nie ma sensu, +to ScalaNative może zastąpić inne języki używane do wdrażania aplikacji i testowania. +Zwłaszcza, że zwykle i tak są to języki jednowątkowe. + +## Portable Scala - wszystkie części mocy + +W łatwy sposób można stworzyć projekt, który będzie kompilowany na wszystkie trzy platformy, +to znaczy JS, JVM i Native. + +Na początek instalujemy [zależności] dla **[Scala Native]**: + +```bash +sudo apt install clang libunwind-dev +sudo apt install libgc-dev libre2-dev +``` + +Następnie pobieramy przykładową [aplikację skośną] z portable-scala: +```bash +sbt new portable-scala/sbt-crossproject.g8 +``` + +Kompilujemy: +```bash +sbt clean compile test +``` + +I uruchamiamy: +```bash +sbt barJS/run barJVM/run barNative/run +``` + +## Mój Resentiment + +Stworzyłem projekt na portalu [GitHub], +gdzie będę starał się rozwijać aplikację kompilowaną na wszystkie trzy platformy. +Na razie pod tagiem [portable-scala] +znajduje się wersja z podniesionymi zależnościami i ze zmienioną konfiguracją projektu. + +Pobranie projektu: +``` +git clone https://github.com/writeonly/resentiment.git +``` + +Kompilacja: +```bash +sbt clean compile test +``` + +I uruchomienie: +```bash +sbt re/run reJS/run reJVM/run +``` + +[Crystal]: /langs/crystal +[Erlang]: /langs/erlang +[Go]: /langs/go +[Haskell]: /langs/haskell +[JavaScript]: /langs/javascript +[Pony]: /langs/pony +[Rust]: /langs/rust +[Scala]: /langs/scala + +[C]: /tools/clang +[JVM]: /tools/jvm +[LLVM]: /tools/llvm +[Node.js]: /tools/node-js +[Scala Native]: /tools/scala-native +[Scala.js]: /tools/scala-js + +[Akka.js]: /libs/akka-js + +[Transpilator]: /tags/transpiler +[Kompilator]: /tags/compiler + +[zależności]: http://www.scala-native.org/en/v0.3.8/user/setup.html#installing-clang-and-runtime-dependencies +[aplikację skośną]: https://github.com/portable-scala/sbt-crossproject.g8 + +[GitHub]: https://github.com/writeonly/resentiment +[portable-scala]: https://github.com/writeonly/resentiment/tree/portable-scala diff --git a/_collections/_posts/2018-10-10-git-flow-i-aliasy.md b/_collections/_posts/2018-10-10-git-flow-i-aliasy.md new file mode 100644 index 00000000..0c818f5a --- /dev/null +++ b/_collections/_posts/2018-10-10-git-flow-i-aliasy.md @@ -0,0 +1,79 @@ +--- +title: "Git-flow i aliasy" +author: TheKamilAdam +category: cli +tags: alias cli +labels: flow +tools: git +redirect_from: + - git-flow-i-aliasy + - cli/git-flow-i-aliasy + - cli/2018/10/10/git-flow-i-aliasy.html +--- + +Gitflow jest wspaniałą koncepcją pracy z gałęziami w repozytorium Git. +Strategia ta jest świetnie opisana na +[A successful Git branching model](). + +Jednak początkowo może wydawać się zbyt skomplikowana. +Straszy zwłaszcza ilością poleceń, które trzeba wykonać, żeby scalić gałąź z nową funkcjonalnością: +```bash +$ git checkout develop +$ git merge --no-ff myfeature +$ git branch -d myfeature +$ git push origin develop +``` + +Ilość poleceń, parametrów i przełączników może powodować niekończące się problemy i dyskusje + "czy na pewno potrzebujemy czegoś tak skomplikowanego?". + +Na szczęście istnieje 'git-flow'. + +## Narzędzie git-flow + +> git-flow jest zbiorem rozszerzeń gita dostarczającym wysokopoziomowe operacje na repozytorium, + wspierającym strategię rozgałęziania opracowaną przez Vincenta Driessena. +Za [ściągawka do git-flow]() + +Tutaj już nie mogą toczyć się dyskusje czy powinniśmy scalać z przełącznikiem `--no-ff` czy bez niego. +Możemy wziąć całe narzędzie ustandaryzowane i przetestowane przez społeczność i nie kroimy niczego własnego. + +Zalety tego są oczywiste: +* programista, tester i/lub wdrożeniowiec, +który raz nauczył się pracować z Gitflow ma jedną rzecz mniej do nauki przy przenoszeniu się do innego zespołu, +gdzie będą stosować dokładnie ten sam Gitflow bez żadnych lokalnych modyfikacji +* zamiast wpisywania długich wielolinijkowców w konsoli możemy używać pojedynczych poleceń. + +## Moje aliasy + +Jednak nawet te polecenia są dla mnie za długie. +Dlatego przygotowałem [plik]() z [aliasami Basha](/git-submoduly-i-aliasy) + +```bash +# git flow +git config --global alias.fi 'flow init' +# git flow feature +git config --global alias.ffstart 'flow feature start' +git config --global alias.fffinish 'flow feature finish ' +git config --global alias.ffpublish 'flow feature publish' +git config --global alias.ffpull 'flow feature pull origin' +git config --global alias.fftrack 'git flow feature track' +# git flow release +git config --global alias.frstart 'flow release start' +git config --global alias.frpusblish 'flow release publish' +git config --global alias.frfinish 'flow release finish' +# git flow hotfix +git config --global alias.fhstart 'flow hotfix start' +git config --global alias.fhfinish 'flow hotfix finish' +``` + +Można go zastosować poleceniem +```bash +curl -s https://raw.githubusercontent.com/writeonly/cli/master/git_config.sh | bash +``` + +i cieszyć się krótkimi poleceniami jak: +```bash +git ffstart myfeature +git fffinish myfeature +``` diff --git a/_collections/_posts/2018-10-17-dynamiczna-analiza-kodu.md b/_collections/_posts/2018-10-17-dynamiczna-analiza-kodu.md new file mode 100644 index 00000000..ea45d0ba --- /dev/null +++ b/_collections/_posts/2018-10-17-dynamiczna-analiza-kodu.md @@ -0,0 +1,183 @@ +--- +title: "Dynamiczna analiza kodu dla SBT - testy jednostkowe" +author: TheKamilAdam +category: scala-native +tags: code-analysis dynamic-code-analysis +labels: minitest greenlight +langs: scala +tools: scala-jvm scala-js scala-native +libs: specs2 scalatest utest +redirect_from: + - dynamiczna-analiza-kodu + - scala-native/dynamiczna-analiza-kodu + - resentiment/dynamiczna-analiza-kodu + - resentiment/2018/10/17/dynamiczna-analiza-kodu.html +--- + +> Dynamiczna analiza programu to analiza oprogramowania komputerowego wykonywanego przez wykonywanie programów na rzeczywistym lub wirtualnym procesorze. +> Korzystanie z metryk testów, takich jak pokrycie kodu, zapewnia, że przetestowano odpowiednią ilość możliwych zachować programu. +> Aby analiza dynamiczna programu była skuteczna, program docelowy musi być wykonany z wystarczającą ilością danych wejściowych do testów, aby uzyskać interesujące zachowanie. +> Testy jednostkowe, testy integracyjne, testy systemowe i testy akceptacyjne wykorzystują dynamiczną analizę programu. + +Za [wikipedią](). + +W tym poście skupię się tylko na frameworkach do testów, testach jednostkowych i mierzeniu pokrycia kodu testami. + +## Frameworki dla testów + +* [ScalaTest]() - +jest to chyba najbardziej znany i rozbudowany framework dla testów do języka Scala. +Wspiera Scala.js w wersji 0.6.x. Ostatnia wersja snapshot wspiera Scala Native. +Posiada osiem różnych [stylów pisania testów](), +jednak autorzy zachęcają do wybrania dwóch dla projektu. +Jeden styl dla testów jednostkowo-integracyjnych, drugi - dla akceptacyjnych. +Najciekawsze style to: + * `FunSuite` i `FlatSpec` - są to proste, płaskie style pisania testów podobne do JUnit. + Jeśli jednak są dla kogoś zbyt awangardowe jest możliwość pisania testów w Scali z użyciem [JUnit i assercji z ScalaTest]() + * `FunSpec`, `FreeSpec` i `WordSpec` - są to style testów umożliwiające pisanie zagnieżdżonych testów, + jednak zagnieżdżenia nie są wymagane (za wyjątkiem stylu `FunSpec`, gdzie trzeba użyć przynajmniej jeden poziom `Describe`) + * `FeatureSpec` - jest to zaawansowany styl dla pisania testów akceptacyjnych. +* [specs2]() - +jest to drugi najbardziej znany framework do pisania testów dla języka Scala. +Od wersji czwartej wspiera Scala.js w wersji 0.6.x. +Ma dwa style pisania testów: + * `org.specs2.mutable.Specificatio` - najbardziej przypomina `FreeSpec` i jest przewidziany do pisania testów jednostkowych i integracyjnych. + * `org.specs2.Specification` - styl testów przewidziany do pisania testów akceptacyjnych, +* [uTest]() - +czarny koń tego zestawienia. +Wspiera Scala.js w wersji 0.6.x i 1.0.x oraz Scala Native. +Autor frameworka skromnie chwali się, że wspiera wszystkie wersje języka Scala. +Ma jeden styl pisania testów który wygląda jak `FreeTest`. +* [MiniTest]() - +stworzony przez [Monix]() do testowania swojej biblioteki. +Wspiera Scala.js w wersji 0.6.x. +Ma jeden styl pisania testów, który wygląda jak `FunSuite`. +* [Greenlight]() - +projekt niestety umarł. +Wspiera Scala.js w wersji 0.6.x. +Ma jeden styl pisania testów, który wygląda jak `FlatSpec` + +## Test jednostkowy w uTest + +W `build.sbt` dodajemy `uTest` do zależności projektu: +```scala + libraryDependencies += "com.lihaoyi" %%% "utest" % "0.6.5" % "test" +``` + +i ustawiamy jako framework testowy: +```scala + testFrameworks += new TestFramework("utest.runner.Framework"), +``` + +Tworzymy klasę `Calculator`, którą będziemy testować : +```scala +package pl.writeonly.re.shared + +class Calculator { + type T = Int + + def add(a: T, b: T): T = a * b + + def mul(a: T, b: T): T = a + b + + def leq(a: T, b: T): Boolean = a < b + +} +``` + +Oraz testy dla niej: + +```scala +package pl.writeonly.re.shared + +import utest._ + +object CalculatorTest extends TestSuite { + override val tests: Tests = Tests { + val calculator = new Calculator() + 'addition - { + val addition: (Int, Int) => Int = (x, y) => calculator.add(x, y) + "0 + 0 == 0" - { + assert(addition(0, 0) == 0) + } + "2 + 2 == 4" - { + assert(addition(2, 2) == 4) + } + } + 'multiplication - { + val multiplication: (Int, Int) => Int = (x, y) => calculator.mul(x, y) + "0 + 0 == 0" - { + assert(multiplication(0, 0) == 0) + } + "2 + 2 == 4" - { + assert(multiplication(2, 2) == 4) + } + } + 'less_or_equal - { + val less_or_equal: (Int, Int) => Boolean = (x, y) => calculator.leq(x, y) + "0 <= 2 == true" - { + assert(less_or_equal(0, 2)) + } + "2 <= 0 == false" - { + assert(!less_or_equal(2, 0)) + } + } + } +} +``` + +Wszystko kompilujemy i uruchamiamy testy za pomocą polecenia: +```bash +sbt clean compile test +``` + +Testy przeszły, jesteśmy szczęśliwi: +```log +[info] -------------------------------- Running Tests -------------------------------- +[info] + pl.writeonly.re.shared.CalculatorTest.addition.0 + 0 == 0 0ms +[info] + pl.writeonly.re.shared.CalculatorTest.addition.2 + 2 == 4 0ms +[info] + pl.writeonly.re.shared.CalculatorTest.multiplication.0 + 0 == 0 0ms +[info] + pl.writeonly.re.shared.CalculatorTest.multiplication.2 + 2 == 4 0ms +[info] + pl.writeonly.re.shared.CalculatorTest.less_or_equal.0 <= 2 == true 0ms +[info] + pl.writeonly.re.shared.CalculatorTest.less_or_equal.2 <= 0 == false 0ms +[info] Tests: 6, Passed: 6, Failed: 0 +``` + +## Testowanie testów - mierzenie pokrycia kodu testami +Skąd mamy mieć pewność, że przetestowaliśmy klasę `Calculator` w wystarczający sposób? +Możemy to częściowo sprawdzić mierząc pokrycie kodu produkcyjnego (tj. klasy `Calculator`) testami. + +Jeśli chodzi o narzędzia do mierzenia pokrycia kodu testami to tutaj król jest jeden +i jest nim [scoverage](). +Posiada on wtyczki do: +* [sbt]() +* [maven]() +* [gradle]() +* [scalac]() +* [sonarqube]() + +Przy czym użyjemy tutaj tylko pierwszej z nich. + +Dodajemy `sbt-scoverage` do `build.sbt`: +```scala +addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.5.1") +``` +I wykonujemy: +```bash +sbt clean coverage test && sbt coverageReport +``` +gdzie: +* `coverage` - wykonuje kompilacje z instrumentacją kodu +* `coverageReport` - generuje raport + +Niestety powyższe polecenie działa tylko dla implementacji Scala/JVM i Scala.js. +Scala Native nie wspiera instrumentacji kodu. +Dlatego projekt [resentiment](https://github.com/writeonly/resentiment) trzeba kompilować za pomocą polecenia: +```bash +sbt clean compile re/test coverage reJVM/test reJS/test && sbt coverageReport +``` + +Teraz możemy otworzyć pliki `/re/js/target/scala-2.11/scoverage-report/index.html` +oraz `/re/jvm/target/scala-2.11/scoverage-report/index.html` +i zobaczyć, że klasa `Calculator` ma 100% pokrycia kodu testami. +Lider nietechniczny i Product Owner powinni być z nas zadowoleni. diff --git a/_collections/_posts/2018-10-24-statyczna-analiza-kodu-1.md b/_collections/_posts/2018-10-24-statyczna-analiza-kodu-1.md new file mode 100644 index 00000000..bf1a928f --- /dev/null +++ b/_collections/_posts/2018-10-24-statyczna-analiza-kodu-1.md @@ -0,0 +1,167 @@ +--- +title: "Statyczna analiza kodu dla języka Scala w SBT - część 1." +author: TheKamilAdam +category: scala-native +tags: code-analysis static-code-analysis +labels: scalafmt scalariform +langs: scala +tools: sbt scalafix +redirect_from: + - statyczna-analiza-kodu-1 + - scala-native/statyczna-analiza-kodu-1 + - resentiment/statyczna-analiza-kodu-1 + - resentiment/2018/10/24/statyczna-analiza-kodu-1.html +--- + +> Statyczna analiza programu to analiza oprogramowania komputerowego wykonywanego bez faktycznego uruchamiania programów, +w przeciwieństwie do analizy dynamicznej, +która jest analizą wykonywaną na programach podczas ich wykonywania. + +> Termin ten jest zwykle stosowany do analizy wykonywanej przez zautomatyzowane narzędzie, +analiza wykonywana przez człowieka jest nazywana przeglądem kodu. + +Za [wikipedią](). + +Jest to moja ulubiona część konfigurowania projektu, +ponieważ odpowiednio dobrany zestaw wtyczek do statycznej analizy kodu +potrafi znacząco skrócić czas potrzebny do zrobienia przeglądu kodu. + +## Wtyczki modyfikujące kod źródłowy + +Z powodu ogromu różnego rodzaju wtyczek do statycznej analizy kodu dla języka Scala +w tym poście skupię się tylko na wtyczkach modyfikujących kod źródłowy. + +### sbt-scalariform - sbt plugin adding support for source code formatting using Scalariform +[sbt-scalariform]() +to wtyczka sbt dodająca obsługę formatowania kodu źródłowego przy użyciu formatera kodu Scalariform + +Dodajemy `scalariform` do pliku `projektu/plugins.sbt`: +```scala +addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.8.2") +``` + +Konfiguracja jest możliwa za pomocą: +* zmiennej `scalariformPreferences` w pliku `build.sbt` +* pliku `.scalariform.conf` + +Formatowanie kodu jest wykonywane automatycznie podczas kompilacji: + +```bash +sbt compile test:compile it:compile +``` + +### Scalafmt - Code formatter for Scala +[Scalafmt]() to formater kodu dla języka Scala. + +Dodajemy `scalafmt` do pliku `projektu/plugins.sbt`: +```scala +addSbtPlugin("com.geirsson" % "sbt-scalafmt" % "1.5.1") +``` + +Konfiguracja jest możliwa za pomocą pliku `.scalafmt.conf`, np.: +```hocon +style=IntelliJ +maxColumn=80 +``` + +Formatowanie domyślnie nie wykonuje się podczas kompilacji. +Aby sformatować kod należy wykonać: +```bash +sbt scalafmtSbt scalafmt test:scalafmt it:scalafmt +``` +Kolejno formatowany jest plik `build.sbt`, kod produkcyjny, testy jednostkowe i testy integracyjne. + +Możliwe jest także tylko sprawdzenie czy kod jest sformatowany poprawnie za pomocą polecenia: +```bash +sbt scalafmtSbtCheck scalafmtCheck test:scalafmtCheck it:scalafmtCheck +``` + +### Scalafix - Refactoring and linting tool for Scala +[Scalafix]() to narzędzie do analizy statycznej kodu w języku Scala. +Jest to jedyne narzędzie, które potrafi znalezione błędy poprawić. + +Dodajemy `scalafix` do pliku `projektu/plugins.sbt`: +```scala +addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.0") +``` + +W pliku `build.sbt` dodajemy następujące linie: +```scala + addCompilerPlugin(scalafixSemanticdb) + scalacOptions ++= Seq( + //"-Xfatal-warnings", // it should be disabled for scalafix + "-Ywarn-adapted-args", // for NoAutoTupling + "-Ywarn-unused", // for RemoveUnused + ) +``` + +Konfiguracja jest możliwa za pomocą pliku `.scalafix.conf`. +Poniższa konfiguracja włącza wszystkie istniejące obecnie reguły: +```hocon +rules = [ + +// Semantic Rules - Reguły semantyczne + NoAutoTupling + RemoveUnused + +// Syntactic Rules - Reguły składniowe + DisableSyntax + LeakingImplicitClassVal + NoValInForComprehension + ProcedureSyntax +] + +DisableSyntax.noVars = true +DisableSyntax.noThrows = true +DisableSyntax.noNulls = true +DisableSyntax.noReturns = true +DisableSyntax.noAsInstanceOf = true +DisableSyntax.noIsInstanceOf = true +DisableSyntax.noXml = true +DisableSyntax.noDefaultArgs = true +DisableSyntax.noFinalVal = true +DisableSyntax.noFinalize = true +DisableSyntax.noValPatterns = true +DisableSyntax.noUniversalEquality = true +DisableSyntax.noUniversalEqualityMessage = "== is unsafe since it allows comparing two unrelated types" +DisableSyntax.regex = [] +``` + +Aby naprawić kod należy wykonać: +```bash +sbt scalafix test:scalafix it:scalafix +``` +Kolejno naprawiany jest kod produkcyjny, testy jednostkowe i testy integracyjne. + +Możliwe jest także tylko sprawdzenie czy kod nie zawiera błędów za pomocą polecenia: +```bash +sbt 'scalafix --check' 'test:scalafix --check' 'it:scalafix --check' +``` + +## Podsumowanie + +Wszystkie wymienione wyżej wtyczki dodałem do projektu +[resentiment](). + +Na chwilę obecna moje polecenie do zbudowania tego projektu to: +```bash +sbt clean compile test:compile it:compile re/test && \ +sbt coverage reJVM/test reJS/test && \ +sbt coverageReport +``` + +Wcześniej jednak powinienem wywołać polecenie refaktoryzującą i formatującą kod: +```bash +sbt scalafix test:scalafix it:scalafix && \ +sbt scalafmtSbt scalafmt test:scalafmt it:scalafmt +``` + +Ewentualnie, gdy robię przegląd kodu mogę sprawdzić czy kod jest poprawny za pomocą polecenia: +```bash +sbt 'scalafix --check' 'test:scalafix --check' 'it:scalafix --check' && \ +sbt scalafmtSbtCheck scalafmtCheck test:scalafmtCheck it:scalafmtCheck +``` + +Niestety ponieważ w testach używam porównania `==` +musiałem zakomentować linię `DisableSyntax.noUniversalEquality` w pliku `.scalafix.conf`. +Problem ten rozwiąże w następnym poście. diff --git a/_collections/_posts/2018-10-31-statyczna-analiza-kodu-2.md b/_collections/_posts/2018-10-31-statyczna-analiza-kodu-2.md new file mode 100644 index 00000000..c0a521c6 --- /dev/null +++ b/_collections/_posts/2018-10-31-statyczna-analiza-kodu-2.md @@ -0,0 +1,176 @@ +--- +title: "Statyczna analiza kodu dla języka Scala w SBT - część 2." +author: TheKamilAdam +category: scala-native +tags: code-analysis static-code-analysis +labels: scalastyle wartremover scapegoat linter scala-clippy sbt-cpd sbt-stats +langs: scala +tools: sbt scala-jvm scala-js scala-native +redirect_from: + - statyczna-analiza-kodu-2 + - scala-native/statyczna-analiza-kodu-2.html + - resentiment/statyczna-analiza-kodu-2.html + - resentiment/2018/10/31/statyczna-analiza-kodu-2.html +--- + +Jest to kontynuacja posta +[Statyczna analiza kodu dla języka Scala w SBT - część 1](/statyczna-analiza-kodu-1.html). + +## Wtyczki nie modyfikujące kodu źródłowego. + +Jest to o wiele większy zestaw wtyczek niż poprzednio. + +### Scalastyle - Scala style checker + +[Scalastyle]() + +Dodajemy `Scalastyle` do pliku `project/plugins.sbt`: +```scala +addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0") +``` + +Generujemy domyślny plik konfiguracyjny `scalastyle-config.xml` zawierający reguły: +```bash +sbt scalastyleGenerateConfig +``` + +Wchodzimy do pliku `scalastyle-config.xml` i zmieniamy poziomy z `warning` na `error`. + +Następnie wyłączamy sprawdzanie nagłówka: +```xml + +``` +A na końcu poprawiamy formatowanie dwuliniowej instrukcji `if`: +```xml + + + + + + +``` + +Teraz analizujemy kod i testy za pomocą polecenia: +```bash +sbt scalastyle test:scalastyle it:scalastyle +``` + +Pełna lista reguł jest dostępna pod linkiem +[rules-1.0.0](). + +Dla mnie najważniejszą funkcjonalnością jest liczenie [złożoności cyklomatycznej](): +```xml + + + + + +``` + +### WartRemover: a flexible scala linter +[WartRemover]() +jest to wtyczka do usuwania brodawek z kodu. +Przez brodawkę autor rozumie brzydkie rzeczy, które można napisać w języku Scala, +bo składnia języka jest zbyt liberalna. +Nazwa wtyczki jest trochę na wyrost, +ponieważ w tej chwili `WartRemover` pozwala tylko odnaleźć brodawki, +a usunąć musimy je sami. + +Dodajemy `wartremover` do pliku `project/plugins.sbt`: +```scala +addSbtPlugin("org.wartremover" % "sbt-wartremover" % "2.3.7") +``` + +W pliku `build.sbt` włączamy `wartremover`: +```scala +wartremoverErrors ++= Warts.unsafe +``` + +Od teraz przy każdej kompilacji będą poszukiwane brodawki. +Pełna lista [brodawkek]() + +### Scapegoat - Scala compiler plugin for static code analysis +[Scapegoat]() to linter dla języka Scala. + +Dodajemy `scapegoat` do pliku `project/plugins.sbt`: +```scala +addSbtPlugin("com.sksamuel.scapegoat" %% "sbt-scapegoat" % "1.3.8") +``` + +Ustawiamy wersję `scapegoat` w `build.sbt`: +```scala +scapegoatVersion := "1.1.0" +``` + +Analizujemy kod za pomocą polecenia: +```bash +sbt scapegoat +``` + +### Linter - Static Analysis Compiler Plugin for Scala +[Linter]() +to niestety nie rozwijany już linter. + +Dodajemy `Linter` do pliku `project/plugins.sbt`: +```scala +addCompilerPlugin("org.psywerx.hairyfotr" %% "linter" % "0.1.17") +``` + +Linter uruchamia się automatycznie podczas kompilacji. + +### Scala clippy - Good advice for Scala compiler errors +[Scala clippy]() +to wtyczka dodająca porady jak poprawić błędy kompilacji. + +Dodajemy `clippy` do pliku `project/plugins.sbt`: +```scala +addSbtPlugin("com.softwaremill.clippy" % "plugin-sbt" % "0.5.3") +``` + +### sbt-cpd - Copy & Paste Detector plugin using PMD for sbt. +[sbt-cpd]() +to wtyczka do wykrywania duplikatów kodu za pomocą Copy/Paste Detector (CPD) z projektu PMD. + +Dodajemy `sbt-cpd` do pliku `project/plugins.sbt`: +```scala +addSbtPlugin("com.github.sbt" % "sbt-cpd" % "2.0.0") +``` + +I analizujemy kod za pomocą polecenia: +```bash +sbt cpd +``` + +### stats - An sbt plugin for source code statistics + +[sbt-stats]() +to wtyczka licząca ilość plików, linii i znaków w projekcie. + +Dodajemy `stats` do pliku `project/plugins.sbt`: +```scala +addSbtPlugin("com.orrsella" % "sbt-stats" % "1.0.7") +``` + +Analizujemy kod za pomocą polecenia: +```bash +sbt stats +``` + +## Podsumowanie + +Wszystkie wymienione wyżej wtyczki dodałem do projektu +[resentiment]() + +Moje polecenie generowania raportów wygląda następująco: +```bash +sbt scalastyle test:scalastyle it:scalastyle && \ +sbt scapegoat && \ +sbt cpd && \ +sbt stats +``` + +Niestety, +ponieważ używam metody `println` w klasie `Core`, +muszę obniżyć poziom raportowania błędów +dla reguły `org.scalastyle.file.RegexChecker` w `ScalaStyle` +z `error` na `warning`. \ No newline at end of file diff --git a/_collections/_posts/2018-11-07-flagi-kompilatora-scalac.md b/_collections/_posts/2018-11-07-flagi-kompilatora-scalac.md new file mode 100644 index 00000000..2f7aa2e0 --- /dev/null +++ b/_collections/_posts/2018-11-07-flagi-kompilatora-scalac.md @@ -0,0 +1,156 @@ +--- +title: "Flagi kompilatora Scalac" +author: TheKamilAdam +category: scala-native +tags: compiler +labels: scalafix scalac +langs: perl scala +tools: sbt scalafix +redirect_from: + - flagi-kompilatora-scalac + - scala-native/flagi-kompilatora-scalac + - resentiment/flagi-kompilatora-scalac + - resentiment/2018/11/07/flagi-kompilatora-scalac.html +--- + +Nie bójmy się tego powiedzieć, Scala to nowy **[Perl](/langs/perl)**. +I tak jak w Perlu, w Scali obowiązuje zasada TIMTOWTDI (ang. There is more than one way to do it), +czyli "Można to zrobić na różne sposoby". + +Jednak z biegiem czasu twórcy języka Scala uznali, +że niektóre sposoby są lepsze od innych i powinna istnieć możliwość wyłączenia gorszych sposobów. +Dodatkowo niektóre funkcjonalności języka są tak inne od tego co do tej pory widzieli programiści języków obiektowych, +że nie powinny być domyślnie włączone. +Oba te warunki, i pewnie jeszcze kilka innych, powodują, że Scalac, **[kompilator](/tags/compiler)** języka Scala, +posiada [flagi kompilacji](). +Dokładniej Scalac posiada ogromną ilość flag kompilacji. + +## Rekomendowana lista flag kompilatora + +Na szczęście istnieją tacy ludzie jak [tpolecat](), +który na swoim blogu zebrał listę [rekomendowanych flag kompilatora](https://tpolecat.github.io/2017/04/25/scalac-flags.html) +Są to: +```scala +scalacOptions ++= Seq( + "-deprecation", // Emit warning and location for usages of deprecated APIs. + "-encoding", "utf-8", // Specify character encoding used by source files. + "-explaintypes", // Explain type errors in more detail. + "-feature", // Emit warning and location for usages of features that should be imported explicitly. + "-language:existentials", // Existential types (besides wildcard types) can be written and inferred + "-language:experimental.macros", // Allow macro definition (besides implementation and application) + "-language:higherKinds", // Allow higher-kinded types + "-language:implicitConversions", // Allow definition of implicit functions called views + "-unchecked", // Enable additional warnings where generated code depends on assumptions. + "-Xcheckinit", // Wrap field accessors to throw an exception on uninitialized access. + "-Xfatal-warnings", // Fail the compilation if there are any warnings. + "-Xfuture", // Turn on future language features. + "-Xlint:adapted-args", // Warn if an argument list is modified to match the receiver. + "-Xlint:by-name-right-associative", // By-name parameter of right associative operator. + "-Xlint:constant", // Evaluation of a constant arithmetic expression results in an error. + "-Xlint:delayedinit-select", // Selecting member of DelayedInit. + "-Xlint:doc-detached", // A Scaladoc comment appears to be detached from its element. + "-Xlint:inaccessible", // Warn about inaccessible types in method signatures. + "-Xlint:infer-any", // Warn when a type argument is inferred to be `Any`. + "-Xlint:missing-interpolator", // A string literal appears to be missing an interpolator id. + "-Xlint:nullary-override", // Warn when non-nullary `def f()' overrides nullary `def f'. + "-Xlint:nullary-unit", // Warn when nullary methods return Unit. + "-Xlint:option-implicit", // Option.apply used implicit view. + "-Xlint:package-object-classes", // Class or object defined in package object. + "-Xlint:poly-implicit-overload", // Parameterized overloaded implicit methods are not visible as view bounds. + "-Xlint:private-shadow", // A private field (or class parameter) shadows a superclass field. + "-Xlint:stars-align", // Pattern sequence wildcard must align with sequence component. + "-Xlint:type-parameter-shadow", // A local type parameter shadows a type already in scope. + "-Xlint:unsound-match", // Pattern match may not be typesafe. + "-Yno-adapted-args", // Do not adapt an argument list (either by inserting () or creating a tuple) to match the receiver. + "-Ypartial-unification", // Enable partial unification in type constructor inference + "-Ywarn-dead-code", // Warn when dead code is identified. + "-Ywarn-extra-implicit", // Warn when more than one implicit parameter section is defined. + "-Ywarn-inaccessible", // Warn about inaccessible types in method signatures. + "-Ywarn-infer-any", // Warn when a type argument is inferred to be `Any`. + "-Ywarn-nullary-override", // Warn when non-nullary `def f()' overrides nullary `def f'. + "-Ywarn-nullary-unit", // Warn when nullary methods return Unit. + "-Ywarn-numeric-widen", // Warn when numerics are widened. + "-Ywarn-unused:implicits", // Warn if an implicit parameter is unused. + "-Ywarn-unused:imports", // Warn if an import selector is not referenced. + "-Ywarn-unused:locals", // Warn if a local definition is unused. + "-Ywarn-unused:params", // Warn if a value parameter is unused. + "-Ywarn-unused:patvars", // Warn if a variable bound in a pattern is unused. + "-Ywarn-unused:privates", // Warn if a private member is unused. + "-Ywarn-value-discard" // Warn when non-Unit expression results are unused. +) +``` + +Lista jest długa i działa dla języka Scala w wersji 2.12. +Jeśli używasz języka Scala w wersji wcześniejszej to część flag będziesz musiał wyłączyć. +Dla wersji 2.11 jest to: +```scala +scalacOptions --= Seq( + "-Xlint:constant", + "-Ywarn-extra-implicit", + "-Ywarn-unused:implicits", + "-Ywarn-unused:imports", + "-Ywarn-unused:locals", + "-Ywarn-unused:params", + "-Ywarn-unused:patvars", + "-Ywarn-unused:privates", +) +``` + +## .. i wtyczka do nich + +Lista opcji jest długa i może zaciemniać plik `build.sbt`. +Na szczęście [DavidGregory084](https://github.com/DavidGregory084) +stworzył wtyczkę [sbt-tpolecat](https://github.com/DavidGregory084/sbt-tpolecat) +dodającą flagi kompilatora do projektu. + +W pliku ` project/plugins.sbt` dodajemy: +```scala +addSbtPlugin("io.github.davidgregory084" % "sbt-tpolecat" % "0.1.4") +``` +i wtyczka automatycznie ustawia odpowiednie flagi dla wersji 2.10/2.11/2.12/2.13 + +## Portable Scala & Multi-project + +Jeśli kompilujesz projekt w Scali na różne platformy (JVM/JS/Native) +lub posiadasz [multi-project](), +tak jak ja w projekcie [resentiment](https://github.com/writeonly/resentiment), +to musisz ręcznie dodać flagi dla kompilatora. +Flagi generuje metoda `scalacOptionsFor`, która jako parametr pobiera wersję języka Scala. +Flagi dodajemy do każdego projektu z osobna lub do wydzielonych ustawień jak w moim przypadku: + +```scala +val SharedSettings = Seq( + scalaVersion := "2.11.12", + scalacOptions ++= scalacOptionsFor(scalaVersion.value), + // ... +) +``` + +### ScalaFix i modyfikacja domyślnych flag + +Właśnie ustawiliśmy ponad 30 różnych flag, +ale pewnie w niektórych wypadkach chciałbyś zmodyfikować tę listę. +Np. żeby móc używać wtyczki [ScalaFix](/statyczna-analiza-kodu-1.html). + +Wtyczka ta wymaga dodania dwóch flag (`-Ywarn-adapted-args`, `-Ywarn-unused"`) oraz usunięcia jednej (`-Xfatal-warnings`). +Dla wygody, flagi przypisuję do zmiennych, a następnie dodaje do `scalacOptions`. +```scala +val ScalaFixScalacOptions = Seq( + "-Ywarn-adapted-args", // for NoAutoTupling + "-Ywarn-unused", // for RemoveUnused +) + +val ScalaFixScalacOptionsOff = Seq( + "-Xfatal-warnings", // it should be disabled for scalafix +) + +val SharedSettings = Seq( + scalaVersion := "2.11.12", + scalacOptions ++= scalacOptionsFor(scalaVersion.value), + scalacOptions ++= ScalaFixScalacOptions, + scalacOptions --= ScalaFixScalacOptionsOff, + // ... +) +``` + +W identyczny sposób można włączać i wyłączać każdą inną flagę kompilatora Scalac. diff --git a/_collections/_posts/2018-11-14-bardziej-dynamiczna-analiza-kodu.md b/_collections/_posts/2018-11-14-bardziej-dynamiczna-analiza-kodu.md new file mode 100644 index 00000000..31e0ae64 --- /dev/null +++ b/_collections/_posts/2018-11-14-bardziej-dynamiczna-analiza-kodu.md @@ -0,0 +1,242 @@ +--- +title: "Bardziej dynamiczna analiza kodu dla języka Scala - Property-based testing" +author: TheKamilAdam +category: scala-native +tags: code-analysis dynamic-code-analysis +labels: property-based scalacheck scalaprops nyaya +langs: scala haskell +tools: scala-js scala-native +libs: scalatest scalaz specs2 +redirect_from: + - bardziej-dynamiczna-analiza-kodu + - scala-native/bardziej-dynamiczna-analiza-kodu + - resentiment/bardziej-dynamiczna-analiza-kodu + - resentiment/2018/11/14/bardziej-dynamiczna-analiza-kodu.html +--- + +Testy modułowe (jednostkowe) napisane w poście +[Dynamiczna analiza kodu](/dynamiczna-analiza-kodu.html) +dla projektu [resentiment]() +zawiodły. +Mimo posiadania 100% pokrycia kodu dla klasy Calculator klasa ta nie działała w sposób poprawy. + +To dlatego, że skupiłem się na drugiej linii definicji +> Korzystanie z metryk testów, takich jak pokrycie kodu, zapewnia, +że przetestowano odpowiednią ilość możliwych zachować programu + +Zapominając jednocześnie o trzeciej: +> Aby analiza dynamiczna programu była skuteczna, +> program docelowy musi być wykonany z wystarczającą ilością danych wejściowych do testów, +> aby uzyskać interesujące zachowanie. + +Problem można rozwiązać za pomocą *property-based testing* + +## Property-based testing (Testowanie oparte na właściwościach) + +Przy pisaniu normalnych testów, czyli modułowych (jednostkowych), integracyjnych i systemowych, +wyznaczamy przypadki brzegowe i klasy równoważności. +Chcemy by danych testowych było jak najmniej, tak by testy wykonywały się jak najszybciej. + +W przypadku *property-based testing* jest inaczej. +Tutaj zamiast wyznaczać konkretne dane wejściowe definiujemy tylko ogólne ograniczenia jakie mają spełniać dane. +Na podstawie ograniczeń generowane są dane wejściowe dla testów. +Dużo danych wejściowych. +Dlatego testy te są wolne, chociaż testują pojedyncze moduły i jednostki. + +## Biblioteki dla property-based testing w języku Scala + +* [ScalaCheck]() - +pierwsza i najbardziej popularna biblioteka *property-based testing*. +Wspiera Scala.js w wersji 0.6 i 1.0.0. +Inspirowana biblioteką [QuickCheck]() dla języka **[Haskell]**. +Jeden z projektów [typelevel](). +Posiada integracje z [ScalaTest]() +i [Specs2](). +* [scalaprops]() - +druga najbardziej popularna biblioteka *property-based testing*. +Wspiera **[Scala.js]** w wersji 0.6 i **[Scala Native]** w wersji 0.3. +Posiada integrację z biblioteką **[Scalaz]**. +* [Nyaya]() - +projekt niestety umarł. +Wspierał Scala.js w wersji 0.6. + +## Testowanie oparte na właściwościach za pomocą ScalaProps +Ponieważ chcę utrzymać możliwość kompilacji krzyżowej (cross compilation), +wybieram bibliotekę `scalaprops` dla testów. + +Dodajemy wtyczkę `sbt-scalaprops` do pliku `project/plugins.sbt`: +``` +addSbtPlugin("com.github.scalaprops" % "sbt-scalaprops" % "0.2.6") +``` + +Dodajemy wymagane zależności do `libraryDependencies`: +```scala + libraryDependencies ++= Seq( + "com.github.scalaprops" %%% "scalaprops" % ScalaPropsVersion % "test,it", + "com.github.scalaprops" %%% "scalaprops-scalazlaws" % ScalaPropsVersion % "test,it", + ), +``` + +Ponieważ testy jednostkowe powinny być szybkie, +konfigurujemy `scalaprops` jako testy integracyjne. + +Na początku musimy dodać do cross-projektu ustawienia dla `scalaprops` za pomocą linii: +```scala +lazy val re = crossProject(JSPlatform, JVMPlatform, NativePlatform) + // ... + .settings(scalapropsCoreSettings) +``` + +Następnie musimy wskazać folder, który będzie zawierać testy integracyjne: +```scala +lazy val re = crossProject(JSPlatform, JVMPlatform, NativePlatform) + // ... + .settings( + unmanagedSourceDirectories in IntegrationTest ++= CrossType.Full.sharedSrcDir(baseDirectory.value, "it").toSeq + ) +``` + +Niestety Scala Native nie wspiera obecnie testów integracyjnych. +Może kiedyś będzie wspierać, +może jak będę miał czas sam ogarnę makra i napiszę stosownego pull-requesta. +Do tego czasu będzie mi o tym przypominać zakomentowana linia: +```scala +lazy val re = crossProject(JSPlatform, JVMPlatform, NativePlatform) + // ... + //.nativeSettings(scalapropsNativeSettings) +``` + +Ostatecznie konfiguracja projektu wygląda następująco: +```scala +lazy val re = crossProject(JSPlatform, JVMPlatform, NativePlatform) + .withoutSuffixFor(NativePlatform) + .crossType(CrossType.Full) + .settings(SharedSettings) + .jsSettings(jsSettings) + .jvmSettings(jvmSettings) + .nativeSettings(nativeSettings) + // IntegrationTest + .configs(IntegrationTest) + .settings(Defaults.itSettings) + .settings( + inConfig(IntegrationTest)(scalafixConfigSettings(IntegrationTest)), + inConfig(IntegrationTest)(ScalafmtPlugin.scalafmtConfigSettings), + inConfig(IntegrationTest)(scalariformItSettings), + unmanagedSourceDirectories in IntegrationTest ++= CrossType.Full.sharedSrcDir(baseDirectory.value, "it").toSeq + ) + .jsSettings(inConfig(IntegrationTest)(ScalaJSPlugin.testConfigSettings)) + .nativeSettings(inConfig(IntegrationTest)(Defaults.testSettings)) + // PropsTest + .settings(scalapropsCoreSettings) + //.nativeSettings(scalapropsNativeSettings) +``` + +W folderze `re/shared/src/it/scala/` tworzymy testy dla klasy `pl.writeonly.re.shared.Calculator`: +```scala +package pl.writeonly.re.shared + +import scalaprops.{ Property, Scalaprops } + +object CalculatorIT extends Scalaprops { + val calculator = new Calculator() + + val addition: (Int, Int) => Int = (x, y) => calculator.add(x, y) + val additionTest = Property.forAll { (a: Int, b: Int) => + addition(a, b) == a + b + } + + val multiplication: (Int, Int) => Int = (x, y) => calculator.mul(x, y) + val multiplicationTest = Property.forAll { (a: Int, b: Int) => + multiplication(a, b) == a * b + } + + val lessOrEqual: (Int, Int) => Boolean = (x, y) => calculator.leq(x, y) + val lessOrEqualTest = Property.forAll { (a: Int, b: Int) => + lessOrEqual(a, b) == (a <= b) + } +} +``` + +Wywołujemy: +```bash +sbt clean coverage reJS/it:test reJVM/it:test +``` + +I naszym oczom powinien ukazać się piękny komunikat: +```bash +pl.writeonly.re.shared.CalculatorIT$ ++- additionTest Falsified(0,0,[Arg(0, 18591416),Arg(0, 241819340)],LongSeed(1542137236582000128)) 4ms ++- lessOrEqualTest ................................................. Passed(50,0,LongSeed(1542137236604999936)) 11ms +`- multiplicationTest Falsified(0,0,[Arg(0, -795557759),Arg(0, -1)],LongSeed(1542137236617999872)) 0ms +[error] falsified CalculatorIT additionTest Falsified(0,0,[Arg(0, 18591416),Arg(0, 241819340)],LongSeed(1542137236582000128)) +[error] falsified CalculatorIT multiplicationTest Falsified(0,0,[Arg(0, -795557759),Arg(0, -1)],LongSeed(1542137236617999872)) +[info] pl.writeonly.re.shared.CalculatorIT$ 39 ms +11 pl.writeonly.re.shared.CalculatorIT$.lessOrEqualTest 50 50 +4 pl.writeonly.re.shared.CalculatorIT$.additionTest 50 50 +0 pl.writeonly.re.shared.CalculatorIT$.multiplicationTest 50 50 +[info] 11 pl.writeonly.re.shared.CalculatorIT$.lessOrEqualTest 50 50 +[info] 4 pl.writeonly.re.shared.CalculatorIT$.additionTest 50 50 +[info] 0 pl.writeonly.re.shared.CalculatorIT$.multiplicationTest 50 50 +[error] Failed tests: +[error] pl.writeonly.re.shared.CalculatorIT +[error] (reJS / IntegrationTest / test) sbt.TestsFailedException: Tests unsuccessful +``` +Testy nie przeszły, mamy błąd w kodzie. W związku z tym poprawiamy klasę `Calculator`: +```scala +package pl.writeonly.re.shared + +class Calculator { + type T = Int + + def add(a: T, b: T): T = a + b + + def mul(a: T, b: T): T = a * b + + def leq(a: T, b: T): Boolean = a < b + +} +``` + +I ponownie wywołujemy: +```bash +sbt clean coverage reJS/it:test reJVM/it:test +``` + +Teraz dostajemy poprawną odpowiedź: +```bash +pl.writeonly.re.shared.CalculatorIT$ ++- additionTest ................................................. Passed(50,0,LongSeed(1542137486777999872)) 12ms ++- lessOrEqualTest ................................................. Passed(50,0,LongSeed(1542137486793999872)) 5ms +`- multiplicationTest ................................................. Passed(50,0,LongSeed(1542137486800999936)) 5ms +[info] pl.writeonly.re.shared.CalculatorIT$ 31 ms +12 pl.writeonly.re.shared.CalculatorIT$.additionTest 50 50 +5 pl.writeonly.re.shared.CalculatorIT$.lessOrEqualTest 50 50 +5 pl.writeonly.re.shared.CalculatorIT$.multiplicationTest 50 50 +[info] 12 pl.writeonly.re.shared.CalculatorIT$.additionTest 50 50 +[info] 5 pl.writeonly.re.shared.CalculatorIT$.lessOrEqualTest 50 50 +[info] 5 pl.writeonly.re.shared.CalculatorIT$.multiplicationTest 50 50 +``` + +Ostatecznie moje pełne polecenie do kompilacji to: +```bash +sbt scalafix test:scalafix it:scalafix && \ +sbt scalafmtSbt scalafmt test:scalafmt it:scalafmt && \ +sbt clean compile test:compile it:compile re/test && \ +sbt coverage reJS/test reJVM/test reJS/it:test reJVM/it:test && \ +sbt coverageReport && \ +sbt scalastyle test:scalastyle it:scalastyle && \ +sbt scapegoat cpd stats +``` + +## Smutne podsumowania +Klasyczne testy modułowe (jednostkowe) nie wystarczają, +ponieważ poprawnie napisane testy modułowe, +które pokrywają 100% kodu aplikacji, +mogą być niepoprawne, jeśli dane wejściowe są źle dobrane. + +[Haskell]: /langs/haskell + +[Scalaz]: /libs/scalaz + +[Scala Native]: /tools/scala-native +[Scala.js]: /tools/scala-js diff --git a/_collections/_posts/2018-12-12-ciagla-intergracja.md b/_collections/_posts/2018-12-12-ciagla-intergracja.md new file mode 100644 index 00000000..c428c41e --- /dev/null +++ b/_collections/_posts/2018-12-12-ciagla-intergracja.md @@ -0,0 +1,275 @@ +--- +title: "Ciągła integracja, ciągła kontrola, ciągła Scala" +author: TheKamilAdam +category: scala-native +labels: coveralls continuous-integration travis-ci +langs: scala java rust +tools: clang sbt scala-native ubuntu +libs: +redirect_from: + - ciagla-intergracja + - scala-native/ciagla-intergracja + - resentiment/ciagla-intergracja + - resentiment/2018/12/12/ciagla-intergracja.html +--- + +W poprzednich wpisach zbudowaliśmy ogromne polecenie +do analizy statycznej i dynamicznej kodu projektu oraz generacji raportów. +Jednak wykonanie tego polecenia trwa. +A programiści nie lubią czekać. + +Istnieje podejrzenie graniczące z pewnością, +że programiści pracujący przy projekcie będą wywoływać polecenie fragmentarycznie, +a całe polecenie tylko przed wysłaniem kodu do repozytorium. +O ile i tego nie zapomną lub zignorują. + +W scentralizowanych systemach kontroli wersji takich jak SVN lub CVS +problem ten rozwiązywano za pomocą *hooków* po stronie klienta (tj programisty). +Np. nie można było zrobić *commita*, jeśli kod nie był sformatowany, +a pokrycie kodu testami na odpowiednio wysokim poziomie. +Nie było to jednak dobre rozwiązanie ponieważ każdą walidację po stronie klienta można oszukać, obejść i/lub wyłączyć. + +Dziś istnieją zdecentralizowane systemy kontroli wersji jak Git czy Mercurial. +Pozwalają one w łatwy sposób tworzyć *feature branche*, +dzięki czemu kod nie jest wysyłany bezpośrednio do głównej gałęzi repozytorium. +*Feature branche* nie muszą zawierać sformatowanego kodu, nie muszą się nawet kompilować. + +Jednocześnie chcielibyśmy mieć pewność, że w momencie łączenia *feature branch* z główną gałęzią repozytorium, +kod zawarty w *feature branchy* działa poprawnie i spełnia standardy zdefiniowane w projekcie. +Rozwiązaniem jest tutaj serwer ciągłej integracji. + +## Serwer ciągłej integracji i zamieszanie ze słownictwem + +Serwer ciągłej integracji jest to serwer konfigurowany skryptem, zwanym także *pipeline*. +Większość serwerów, w zależności od konfiguracji jest wstanie robić trzy rzeczy: +* ciągłą integrację +* ciągłe dostarczanie +* ciągłe wdrażanie + +**Ciągła integracja** (ang. *Continuous Integration*, *CI*) jest to proces, +który powinien wykonać się po każdym *commicie* wysłanym do zdalnego repozytorium kodu źródłowego. +W jego skład wchodzą: +* sprawdzenie poprawności formatowania +* analiza statyczna +* kompilacja +* analiza dynamiczna (testy jednostkowe i integracyjne) +* generowanie raportów + +i wszystko inne co zostanie uznane za słuszne dla pojedynczego *commitu*. + +**Ciągłe dostarczanie** (ang. *Continuous Delivery*, *CD*) jest to proces, +który powinien wykonać się po każdym *commicie* (zwykle *merge'u*) do gałęzi głównej (np. master/develop). +Składa się ze wszystkich etapów ciągłej integracji plus dodatkowo: +* nadania numeru wersji (głównie w przypadku bibliotek) +* zbudowaniu paczki wykonywalnej (biblioteki, mikroserwisu, aplikacji) +* wdrożeniu na serwer developerski (w przypadku mikroserwisów i aplikacji) +i uruchomieniu testów systemowych oraz akceptacyjnych, a następnie wdrożeniu na serwer testowy/demonstracyjny +* opublikowaniu w repozytorium artefaktów (głównie w przypadku bibliotek) + +Oczywiście jest to tylko jedna z wielu wersji procesu. +Możliwe punkty zmiany to np.: +* polityka firmy może zakładać, że numery wersji bibliotek powinny być nadawane ręcznie +* aplikacja jest na tyle duża, że niemożliwością jest uruchamianie wszystkich testów po każdej zmianie + +**Ciągłe wdrażanie** (ang. *Continuous Deployment*) jest rozszerzeniem procesu ciągłego dostarczania dla aplikacji +i zawiera tylko jeden dodatkowy punkt, zaufanie. Zaufanie, że: +* aplikacja została odpowiednio przetestowana +* jeśli włączy się alarm, sygnalizujący błąd w aplikacji, to ktoś się nim zajmie + +Dodatkowy krok polega na automatycznym wdrażaniu wydanej aplikacji na serwer produkcyjny. + +Teoretycznie możnaby wprowadzać podział na serwery CI i serwery CD. +Jednak jeśli z poziomu konfiguracji serwera CI mamy dostęp do basha, +lub możemy pisać wtyczki w innych językach programowania, +to z łatwością możemy zamienić serwer CI w serwer CD. +Łatwo więc zauważyć że granica jest tutaj bardzo płynna. + +## Wybór serwera CI/CD + +W świecie Javy jeśli ktoś mówi o serwerze CI zwykle ma na myśli Jenkinsa. +Dostępnych jest jednak wiele serwerów ciągłej integracji. +Chcąc jednak jak najszybciej (najprościej) pokazać zalety ciągłej integracji należy wybrać oprogramowanie darmowe +i dodatkowo dostępne jako usługa (ang. *Software as a Service*, *SaaS*). +Dobrze także, aby *po wyjęciu z pudełka* wspierało używane przez nas języki programowania. +Przy takich założeniach wybór padł na dwa serwisy: +* popularniejszy [Travis CI]() używający kontenerów z **[Ubuntu]** +* młodszy [CircleCI]() używający kontenerów z Debianem + +Niestety nie udało mi się skonfigurować CircleCI dla języka **[ScalaNative]**. +Problemem były zależności dla Debiana. + +Dodatkowo przydatne są także serwisy agregujące raporty z pokrycia kodu testami. +Ja znalazłem dwa działające jako serwis: +* [Code Coverage Done Right | Codecov]() +* [Coveralls - Test Coverage History & Statistics]() + +oba są darmowe dla projektów opensource. + +## Konfiguracja generowania raportów + +Do pliku `project/plugins.sbt` dodajemy dwie wtyczki: +```yaml +addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.5.1") +addSbtPlugin("org.scoverage" % "sbt-coveralls" % "1.2.7") +``` +* [sbt-scoverage]() umożliwia generowanie raportów z pokrycia kodu testami, +* [sbt-coveralls]() umożliwia wysłanie raportu +do [Coveralls]() + +## Konfiguracja projektu dla Travis Ci + +TravisCi jest konfigurowany za pomocą pliku `.travis.yml`. + +Najpierw wybieramy język programowania, jego wersję, wersję Ubuntu oraz wersję maszyny wirtualnej Javy: +```yaml +language: scala +scala: 2.11.12 +dist: xenial +jdk: openjdk8 +``` + +Niestety `openjdk-8-jdk` nie jest domyślnie zainstalowane na Ubuntu w wersji `xenial`. +Na szczęście możemy doinstalować potrzebną nam wersję Javy z pakietów Ubuntu. +Pozostałe pakiety są dla ScalaNative +```yaml +addons: + apt: + packages: + - openjdk-8-jdk + - libunwind-dev + - libgc-dev + - libre2-dev + - clang-6.0 +``` + +Niestety to nie wystarcza i musimy podmienić wersję Javy w zmiennej środowiskowej `PATH`: +```yaml +env: + global: + - JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/ + - PATH=$JAVA_HOME/bin:$PATH +``` + +Włączamy cache dla folderów zawierających zależności: +```yaml +cache: + directories: + - $HOME/.sbt + - $HOME/.ivy2/cache +``` + +Uruchamiamy analizę statyczną i analizę dynamiczną kodu oraz generujemy raport z testów: +```yaml +script: + - sbt 'scalafix --check' 'test:scalafix --check' 'it:scalafix --check' && + sbt scalafmtSbtCheck scalafmtCheck test:scalafmtCheck it:scalafmtCheck && + sbt clean re/compile re/test:compile re/it:compile && + sbt coverage reJS/test reJVM/test reJS/it:test reJVM/it:test coverageReport && + sbt coverageAggregate && + sbt scalastyle test:scalastyle it:scalastyle && + sbt scapegoat cpd stats +``` + +Przesyłamy raport do usług agregujących wyniki testów: +```yaml +after_success: + - sbt coveralls + - bash <(curl -s https://codecov.io/bash) +``` + +Pełny plik konfiguracyjny `.travis.yml`: +```yaml +language: scala +scala: 2.11.12 +dist: xenial +jdk: openjdk8 + +addons: + apt: + packages: + - openjdk-8-jdk + - libunwind-dev + - libgc-dev + - libre2-dev + - clang-6.0 + +env: + global: + - JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/ + - PATH=$JAVA_HOME/bin:$PATH + +cache: + directories: + - $HOME/.ivy2/cache + - $HOME/.sbt + +script: + - sbt 'scalafix --check' 'test:scalafix --check' 'it:scalafix --check' && + sbt scalafmtSbtCheck scalafmtCheck test:scalafmtCheck it:scalafmtCheck && + sbt clean re/compile re/test:compile re/it:compile && + sbt coverage reJS/test reJVM/test reJS/it:test reJVM/it:test coverageReport && + sbt coverageAggregate && + sbt scalastyle test:scalastyle it:scalastyle && + sbt scapegoat cpd stats + +after_success: + - sbt coveralls + - bash <(curl -s https://codecov.io/bash) +``` + +## Podsumowanie + +Uważny czytelnik może zauważyć, że nie wywołuje testów dla **[ScalaNative]**. +Mimo zainstalowania wszystkich pakietów wywołanie testów dla ScalaNative kończy się błędem: +```bash +[error] /usr/bin/ld: warning: libunwind.so.8, needed by /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu/libunwind-x86_64.so, may conflict with libunwind.so.1 +[error] /usr/bin/ld: /home/travis/build/writeonly/resentiment/re/native/target/scala-2.11/native/lib/gc/immix/Heap.c.o: undefined reference to symbol '_Ux86_64_getcontext' +[error] //usr/lib/x86_64-linux-gnu/libunwind.so.8: error adding symbols: DSO missing from command line +[error] clang: error: linker command failed with exit code 1 (use -v to see invocation) +[info] Linking native code (immix gc) (184 ms) +[info] Starting process '/home/travis/build/writeonly/resentiment/re/native/target/scala-2.11/re-out' on port '32951'. +Exception in thread "Thread-386" java.io.IOException: Cannot run program "/home/travis/build/writeonly/resentiment/re/native/target/scala-2.11/re-out": error=2, No such file or directory + at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048) + at scala.sys.process.ProcessBuilderImpl$Simple.run(ProcessBuilderImpl.scala:71) + at scala.sys.process.ProcessBuilderImpl$AbstractBuilder.run(ProcessBuilderImpl.scala:102) + at scala.sys.process.ProcessBuilderImpl$AbstractBuilder.$anonfun$runBuffered$1(ProcessBuilderImpl.scala:150) + at scala.runtime.java8.JFunction0$mcI$sp.apply(JFunction0$mcI$sp.java:12) + at scala.sys.process.ProcessLogger$$anon$1.buffer(ProcessLogger.scala:99) + at scala.sys.process.ProcessBuilderImpl$AbstractBuilder.runBuffered(ProcessBuilderImpl.scala:150) + at scala.sys.process.ProcessBuilderImpl$AbstractBuilder.$bang(ProcessBuilderImpl.scala:116) + at scala.scalanative.testinterface.ComRunner$$anon$1.run(ComRunner.scala:31) +Caused by: java.io.IOException: error=2, No such file or directory + at java.lang.UNIXProcess.forkAndExec(Native Method) + at java.lang.UNIXProcess.(UNIXProcess.java:247) + at java.lang.ProcessImpl.start(ProcessImpl.java:134) + at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029) + ... 8 more +``` + +Jest to kolejny problem **[ScalaNative])**. po braku możliwości wygenerowania pokrycia kodu +oraz braku możliwości uruchomienia testów integracyjnych. +Dowodzi to że ScalaNative niestety dalej jest zabawką +i jeśli chce się pisać monady w języku kompilowanym natywnie należy wybrać **[Rust]**. + +## Postscriptum + +Poszukując serwisów CI natrafiłem na jeszcze jeden termin z kategorii *Continuous cośtam*. + +**Ciągła analiza statyczna** (ang. *Continuous static analysis*) jest to proces podobny do ciągłej integracji, ale ograniczony tylko do jednego kroku, +analizy statycznej. +Cechą charakterystyczną serwerów ciągłej analizy statycznej jest posiadanie ogromnej ilości reguł według których sprawdzany jest kod. +Klasycznym przykładem oprogramowania w świecie Javy jest tutaj [SonarQube](). +Ja oczywiście poszukiwałem oprogramowania działającego jako darmowa usługa dla projektów opensorsowych i znalazłem: +* [Codacy: Automated code reviews & code analytics]() +* [Rocro INSPECODE - Code review without the hassle.]() + +## Postscriptum 2 + +Termin **ciągła analiza statyczna** ułożyłem sam, +jednak występujący w jego miejscu termin **ciągła kontrola jakości kodu** (ang. *Continuous Inspection of Code Quality*) +jest według mnie zbyt ogólny. + +[Rust]: /langs/rust + +[Ubuntu]: /tools/ubuntu +[ScalaNative]: /tools/scala-native diff --git a/_collections/_posts/2019-01-09-biblioteki-do-logowania.md b/_collections/_posts/2019-01-09-biblioteki-do-logowania.md new file mode 100644 index 00000000..dbd27711 --- /dev/null +++ b/_collections/_posts/2019-01-09-biblioteki-do-logowania.md @@ -0,0 +1,370 @@ +--- +title: "Biblioteki do logowania dla języka Scala" +author: TheKamilAdam +category: scala-native +tags: library cli factory logging +labels: scala-logging scribe +langs: scala java +tools: scala-js scala-native +lisb: utest slogging +redirect_from: + - biblioteki-do-logowania + - scala-native/biblioteki-do-logowania + - resentiment/biblioteki-do-logowania + - resentiment/2019/01/09/biblioteki-do-logowania.html +--- + +Chcąc dowiedzieć się co dzieje się wewnątrz naszej aplikacji mamy dwie drogi. +Pierwszym sposobem jest debugowanie. +Jednak im więcej wątków w aplikacji i im bardziej komunikują się one w sposób asynchroniczny tym trudniej jest debugować. +Drugim sposobem jest logowanie informacji. +Najprostszym sposobem logowania informacji w Javie jest `System.out.println`, a w Scali upraszcza się to do `println`. +Ale jest to złe z dwóch powodów: +* Po pierwsze, jeśli piszemy aplikację "konsolową" (ang. *command line interface*, **[CLI]**) +to użytkownik będzie niepotrzebnie widział nieinteresujące go informacje z wewnętrznego procesu przetwarzania. +* Tak wypisanych informacji nie można zapisać w bazie danych ani wysłać do innego systemu. + +Dlatego powstały biblioteki do logowania. +Biblioteki takie pozwalają przekierować logi do pliku, zapisać je w bazie danych oraz wysłać je do dowolnego innego systemu. + +## Przegląd bibliotek + +* [scala-logging]() - +wygodna i wydajna biblioteka logowania opakowywująca bibliotekę `SLF4J` dla języka Scala. +Niestety działa tylko dla Scala/JVM +* [util-logging]() - +jest małym opakowaniem wbudowanego logowania Javy, aby uczynić go bardziej przyjaznym dla Scali. +Niestety także, działa tylko dla Scala/JVM +* [scalajs-java-logging]() - +implementacja `java.logging` dla **[Scala.js]**. +Wspiera **[Scala.js]** w wersji 0.6.x i 1.0.x +* [airframe-log]() - +biblioteka do ulepszania logowania aplikacji Scala z kolorami i lokalizacjami kodów źródłowych. +Wspiera Scala.js w wersji 0.6.x i 1.0.x +* [slogging]() - +biblioteka logowania zgodna z `scala-logging` (i `SLF4J`) oparta na makrach +dla Scala/JVM, **[Scala.js]** (wersja 0.6.x) i **[Scala Native]** +* [scribe]() - +praktyczny szkielet logowania, który nie wymaga żadnej innej struktury logowania +i może być w pełni skonfigurowany programowo. +Wspiera **[Scala.js]** w wersji 0.6.x oraz **[Scala Native]**. + +## I konkretne próby zastosowania + +### scala-logging +Jest to najprawdopodobniej najpopularniejsza biblioteka do logowania w języku Scala. +Niestety jej wadą jest to, że działa tylko dla JVM. + +W pliku `build.sbt` dodajemy bibliotekę do wspólnych zależności: +```scala + libraryDependencies ++= Seq( + "com.typesafe.scala-logging" %% "scala-logging" % "3.9.0", + ), +``` + +`Scala-logging` można używać na dwa sposoby. +Za pomocą traitów `StrictLogging` i `LazyLogging`. +Oba traity tworzą zmienną `logger`, która jest loggerem. + +Trait `StrictLogging` inicjalizuje `logger` w momencie utworzenia klasy: +```scala +package com.typesafe.scalalogging + +import org.slf4j.LoggerFactory + +trait StrictLogging { + protected val logger: Logger = Logger(LoggerFactory.getLogger(getClass.getName)) +} +``` + +```scala +package pl.writeonly.re.shared + +import com.typesafe.scalalogging.StrictLogging + +object StrictLoggingCore extends Core with StrictLogging { + def apply(arg: String): Unit = { + logger.info(s"Hello Scala $arg!") + } +} +``` + +Trait `LazyLogging` inicjalizuje `logger` w momencie pierwszego użycia loggera: +```scala +package com.typesafe.scalalogging + +import org.slf4j.LoggerFactory + +trait LazyLogging { + @transient + protected lazy val logger: Logger = Logger(LoggerFactory.getLogger(getClass.getName)) +} +``` + +```scala +package pl.writeonly.re.shared + +import slogging.LazyLogging + +object LazyLoggingCore extends Core with LazyLogging { + def apply(arg: String): Unit = { + logger.info(s"Hello Scala $arg!") + } +} +``` + +Łączymy wszystko w obiekcie `Core`: +```scala +package pl.writeonly.re.shared + +trait Core { + def apply(arg: String): Unit +} + +object Core extends Core { + override def apply(arg: String): Unit = { + StrictLoggingCore(arg) + LazyLoggingCore(arg) + } +} +``` + +Tworzymy test jednostkowy we frameworku **[uTest]**: +```scala +package pl.writeonly.re.shared + +import utest._ + +object CoreTest extends TestSuite { + override val tests: Tests = Tests { + 'core - { + Core("Awesome") + } + } +} +``` + +Wywołujemy: +```bash +sbt clean re/test +``` + +I wszystko się wysypuje, bo `scala-logging` wspiera tylko JVM. + +### slogging +Jest to przepisana biblioteka `scala-logging`, +która działa dla Scala Native, Scala.js oraz oczywiście Scala/JVM. + +W pliku `build.sbt` dodajemy bibliotekę do wspólnych zależności: +```scala + libraryDependencies ++= Seq( + "biz.enef" %%% "slogging" % SloggingVersion, + ), +``` + +`Slogging` używa się identycznie jak `scala-logging`. + +Trait `StrictLogging` inicjalizuje `logger` w momencie utworzenia klasy: +```scala +package slogging + +trait StrictLogging extends LoggerHolder { + protected val logger : Logger = LoggerFactory.getLogger(loggerName) +} +``` + +```scala +package pl.writeonly.re.shared + +import slogging.StrictLogging + +object StrictLoggingCore extends Core with StrictLogging { + def apply(arg: String): Unit = { + logger.info(s"Hello Scala $arg!") + } +} +``` + +Trait `LazyLogging` inicjalizuje `logger` w momencie pierwszego użycia loggera: +```scala +package slogging + +trait LazyLogging extends LoggerHolder { + protected lazy val logger = LoggerFactory.getLogger(loggerName) +} +``` + +```scala +package pl.writeonly.re.shared + +import slogging.LazyLogging + +object LazyLoggingCore extends Core with LazyLogging { + def apply(arg: String): Unit = { + logger.info(s"Hello Scala $arg!") + } +} +``` + +Łączymy wszystko w obiekcie `Core`: +```scala +package pl.writeonly.re.shared + +trait Core { + def apply(arg: String): Unit +} + +object Core extends Core { + override def apply(arg: String): Unit = { + StrictLoggingCore(arg) + LazyLoggingCore(arg) + } +} +``` + +Tworzymy test jednostkowy we frameworku **[uTest]**: +```scala +package pl.writeonly.re.shared + +import utest._ + +object CoreTest extends TestSuite { + override val tests: Tests = Tests { + 'core - { + Core("Awesome") + } + } +} +``` + +Wywołujemy: +```bash +sbt clean re/test +``` + +I wszystko działa! + +### Scribe + +W pliku `build.sbt` dodajemy bibliotekę do wspólnych zależności: +```scala + libraryDependencies ++= Seq( + "com.outr" %%% "scribe" % ScribeVersion, + ), +``` + +`Scribe` można używać na dwa sposoby. +Za pomocą traitu `Logging` oraz za pomocą obiektu pakietu `scribe`. + +Trait `Logging` w prostu sposób tworzy `logger` dla każdej instancji klasy: +```scala +trait Logging { + protected def loggerName: String = getClass.getName + + protected def logger: Logger = Logger(loggerName) +} +``` + +```scala +package pl.writeonly.re.shared + +import scribe.Logging + +object LoggingCore extends Core with Logging { + override def apply(arg: String): Unit = { + logger.info(s"Hello Scala $arg!") + } +} +``` + +Obiekt pakietu `scribe` zawiera magię opartą na makrach, dlatego dziedziczenie nie jest potrzebne: +```scala +package object scribe extends LoggerSupport { + lazy val lineSeparator: String = System.getProperty("line.separator") + + protected[scribe] var disposables = Set.empty[() => Unit] + + override def log[M](record: LogRecord[M]): Unit = Logger(record.className).log(record) + + def dispose(): Unit = disposables.foreach(d => d()) + + implicit class AnyLogging(value: Any) { + def logger: Logger = Logger(value.getClass.getName) + } + + def async[Return](f: => Return): Return = macro Macros.async[Return] + + def future[Return](f: => Return): Future[Return] = macro Macros.future[Return] + + object Execution { + implicit def global: ExecutionContext = macro Macros.executionContext + } +} +``` + +```scala +package pl.writeonly.re.shared + +object ScribeCore extends Core { + def apply(arg: String): Unit = { + scribe.info(s"Hello Scala $arg!") + } +} +``` + +Łączymy wszystko obiektem `Core`: +```scala +package pl.writeonly.re.shared + +trait Core { + def apply(arg: String): Unit +} + +object Core extends Core { + override def apply(arg: String): Unit = { + LoggingCore(arg) + ScribeCore(arg) + } +} +``` + +Tworzymy test: +```scala +package pl.writeonly.re.shared + +import utest._ + +object CoreTest extends TestSuite { + override val tests: Tests = Tests { + 'core - { + Core("Awesome") + } + } +} +``` + +Wywołujemy: +```bash +sbt clean re/test +``` + +Niestety pojawia się błąd: +``` +[error] cannot link: @java.util.Calendar$::getInstance_java.util.Calendar +[error] cannot link: @java.util.Calendar::setTimeInMillis_i64_unit +[error] unable to link +[error] (re / Nativetest / nativeLink) unable to link +``` + +## Podsumowanie + +Jak zwykle składnia Scali pozwala zapisać te same rzeczy prościej niż w Javie, +jednocześnie dzięki temu można wymusić konwencję tworzenia loggerów na etapie kompilacji. +Dzięki temu nie mamy w kodzie loggerów o nazwach innych niż `loggger` jak np. `LOGGER` lub `LOG`. + +[Scala Native]: /tools/scala-native +[Scala.js]: /tools/scala-js + +[uTest]: /libs/utest + +[CLI]: /tags/cli diff --git a/_collections/_posts/2019-01-16-kategorie-i-tagi.md b/_collections/_posts/2019-01-16-kategorie-i-tagi.md new file mode 100644 index 00000000..c0105a5a --- /dev/null +++ b/_collections/_posts/2019-01-16-kategorie-i-tagi.md @@ -0,0 +1,247 @@ +--- +title: "Jekyll - kategorie i tagi" +author: TheKamilAdam +category: jekyll +tags: blog +tools: jekyll +redirect_from: + - kategorie-i-tagi + - jekyll/kategorie-i-tagi + - writeonlydoc/kategorie-i-tagi + - writeonlydoc/2019/01/16/kategorie-i-tagi.html +--- + +Opublikowałem już kilka artykułów na blogu i chciałem je w jakiś sposób pogrupować. +Najlepiej za pomocą kategorii i tagów. + +## Metadane + +Dla każdego postu oprócz zawartości zapisywałem także metadane, +w tym kategorie i tagi. +W przypadku tego artykułu są to: + +{%raw%} +```yaml +--- +#layout: post +title: "Jekyll - kategorie i tagi" +author: TheKamilAdam +category: jekyll +tags: jekyll blog +--- +``` +{%endraw%} + +Artykuł może zawierać wiele tagów, ale musi mieć dokładnie jedną kategorię. + +## Strony pomocnicze + +Jest to najprawdopodobniej największa wada Jekylla. +Dla każdej kategorii i dla każdego taga trzeba utworzyć stronę pomocniczą. +Strony pomocnicze kategorii muszą znajdować się w folderze `_categories`, +a strony pomocnicze tagów w folderze `_tags`. + +Przykładowy strona pomocnicza dla kategorii: + +{%raw%} +```yaml +--- +permalink: /categories/resentiment +labelcategory: "resentiment" +--- +Opis powstawania projektu resentiment. +``` +{%endraw%} + +Przykładowy strona pomocnicza dla tagu: + +{%raw%} +```yaml +--- +permalink: /tools/scala-native +#layout: page-tag +tag: "scala-native" +--- +``` +{%endraw%} + +## Kolekcje + +Ponieważ stron pomocniczych jest dużo, +dlatego źle jest je trzymać w przestrzeni głównej projektu. +Problem ten można rozwiązać za pomocą kolekcji. +W pliku `_config.yml` dodajemy: + +```yaml +collections: + categories: + output: true + tags: + output: true +``` +Od tej pory strony dla kategorii będą znajdować się w katalogu `_categories`, +a strony dla tagów w katalogu `_tags`. + +Ale dla mnie nawet to było za dużo. +Dlatego kolekcje przeniosłem do folderu `data`. +W pliku `_config.yml` dodajemy: +```yaml +collections_dir: data +``` + +Od tej pory: +* w katalogu `data/_categories` znajdują się kategorie artykułów +* w katalogu `data/_posts` znajdują się artykuły +* w katalogu `data/_tags` znajdują się tagi + +## Layouts - układy stron + +W stronach pomocniczych użyliśmy layoutów `page-categories` i `page-tags`. +Teraz trzeba je zdefiniować. + +Układ strony `_layout/page-category.html` zawierający wszystkie artykuły z danej kategorii: + +{%raw%} +```yaml +--- +#layout: default +title: {{ page.category }} +--- +
+ {% include breadcrumbs.html %} +

Kategoria: {{ page.title }}

+ + {{ posts.content }} + +
+ {% for post in site.posts %} + {% if post.category == page.category %} +
+ + {{ post.title }} + + + + +
+
+ {% assign tags = post.tags | sort %} + Tagi: + {% for tag in tags %} + {{ tag }} + {% endfor %} +
+ {% endif %} + {% endfor %} +
+
+``` +{%endraw%} + +Układ strony `_layout/page-tag.html` zawierający wszystkie artykuły z danym tagiem: +{%raw%} +```yaml +--- +#layout: default +title: {{ page.tag }} +--- +
+ {% include breadcrumbs.html %} +

Tag: {{ page.tag | capitalize }}

+ +
+ {% for post in site.posts %} + {% if post.tags contains page.tag %} +
+ + {{ post.title }} + + + + +
+
+ Kategoria : + {{ post.category | capitalize }} +
+ + {% endif %} + {% endfor %} +
+
+``` +{%endraw%} + +W obu przypadkach iterujemy po liście wszystkich artykułów i prostym `if`em wybieramy te które nas interesują. + +## Pages - strony specjalne + +Potrzebujemy jeszcze jednej rzeczy. + +Strona `pages/categories.html` zawierająca listę wszystkich kategorii: +{%raw%} +```yaml +--- +#layout: posts +title: Kategorie +permalink: /categories/ +description: Kategorie artykułów +--- +
+ {% assign categories = site.categories | sort: "title" %} +
+ {% for node in categories %} + {% if node.title != null and node.layout == "page-category" %} +
+ {{ node.title }} +
+
+ {{ node.content }} +
+ {% endif %} + {% endfor %} +
+
+``` +{%endraw%} + +Strona `pages/tags.html` zawierająca listę wszystkich tagów: +{%raw%} +```yaml +--- +#layout: posts +title: Tagi +permalink: /tags/ +description: Tagi artykułów +--- +
+
    + {% assign tags = site.tags | sort: "title" %} + {% for node in tags %} + {% if node.title != null and node.layout == "page-tag" %} +
  • + {{ node.title }} +
  • + {% endif %} + {% endfor %} +
+
+``` +{%endraw%} + +W obu przypadkach pobieramy listę wszystkich kategorii/tagów i sortujemy po tytułach. +A następnie odrzucamy te które nie są poprawne do wyświetlenia, +czyli zawierają błędny `layout` lub nie posiadają tytułu. + +## Podsumowanie + +Żeby wszystko działało trzeba było napisać trochę kodu. +Łącznie 17 stron pomocniczych dla tagów, 3 - dla kategorii, +dwa układy stron i dwie strony specjalne do agregacji kategorii i tagów. +Ale oczywiście nie to zajeło najwięcej czasu. +Największym problemem była wolność jaką daje jekyll, +czyli możliwość zbudowania układów stron w dowolny sposób. diff --git a/_collections/_posts/2019-01-30-no-universal-equality.md b/_collections/_posts/2019-01-30-no-universal-equality.md new file mode 100644 index 00000000..4ee26774 --- /dev/null +++ b/_collections/_posts/2019-01-30-no-universal-equality.md @@ -0,0 +1,179 @@ +--- +title: "Scala - No Universal Equality" +author: TheKamilAdam +category: scala-native +tags: compiler library monad operator type-class +labels: scalatic +langs: haskell java scala +tools: scala-jvm scala-js scala-native scalafix +libs: cats scalatest scalaz utest +projects: resentiment +redirect_from: + - no-universal-equality + - scala-native/no-universal-equality + - resentiment/no-universal-equality + - resentiment/no-universal-equality.html +--- + +Ostatnim błędem zgłaszanym w kodzie projektu **[resentiment]** przez **[scalafix]** +jest "No Universal Equality" wynikający z użycia operatora `==`. + +W języku **[Scala]** obiekty domyślnie porównuje się za pomocą operatora `==`. +Operator ten wywołuje pod spodem znaną z Javy metodę `equals`. +Operator `==` pozwala jednak na bezsensowne porównywanie obiektów, które są różnych klas. +Mimo że poprawnie napisana metoda `equals` zawsze zwróci w takim przypadku `false`. +Np. porównanie `"A" == 'A'` zawsze zwróci `false`, +ponieważ `"A"` jest klasy `String`, a `'A'` jest klasy `Char`. +Umieszczenie czegoś takiego w kodzie zawsze jest błędem programisty i powinno spowodować nieskompilowanie się kodu. +Jest to nazywane problemem `Universal Equality`. +Można ten problem rozwiązać na kilka sposobów. + +## Dotty - Multiversal Equality + +Najprostszym sposobem rozwiązania problemu `Universal Equality` jest poczekać. +Nowa wersja **[kompilator]** Scala - *[Dotty]()* będzie posiadać +[Multiversal Equality]() +co rozwiązuje problem. + +## Biblioteki zewnętrzne +Jeśli jednak jesteście niecierpliwi istnieje kilka bibliotek rozwiązujących ten problem. +Wykorzystują one to, +że Scala pozwala implementować metody, +których wywołanie wygląda jak wywołanie operatora i zwykle tym nowym operatorem jest `===`. + +### Scalactic +**[Scalactic]()** +jest to zestaw utilsów/narzędzi wydzielony ze **[ScalaTest]**, +który może być przydatny także w kodzie produkcyjnym. + +**Scalactic** posiada wiele klas do porównywania wartości, +między innymi klasę `org.scalactic.TypeCheckedTripleEquals`, +która wymaga by oba porównywane obiekty były tej samej klasy. + +Największą zaletą biblioteki **Scalactic** jest to, +że nie zagłębia się w teorię czystego programowania funkcyjnego (ang. *pure functional programming*) +i nie pojawiają się tam takie straszne terminy jak **[monada]** czy **[klasy typów]**. + +### Scalaz i Cats +*Kolejność chronologiczna.* + +Są to dwie wspaniałe biblioteki, które robią ze Scali język funkcyjny przypominający język **[Haskell]**. + +Biblioteki te dzielą się na dwie główne części: +* *Data types* - tutaj znajdują się monady, które są w Haskellu, ale nie ma ich w bibliotece standardowej języka Scala +* *Type classes* - typ konstruktu systemowego, który obsługuje polimorfizm *ad hoc*. + +Zarówno **[Scalaz]** jak i **[Cats]** posiadają klasę `Equal`, +która pozwala porównywać obiekty za pomocą operatora `===`. + +Dobre porównanie obu bibliotek można znaleźć na [githubie](), +chociaż różnice są bardzo małe. +Obie biblioteki wspierają **[scala.js])**, +ale tylko **Scalaz** - **[scala native]**. + +## "No Universal Equality" z Scalaz w projekcie Resentiment + +W `build.sbt` do `SharedSettings` dodajemy bibliotekę `Scalaz`: +```scala + libraryDependencies += "org.scalaz" %%% "scalaz-core" % "7.2.27", +``` + +Jeśli używamy scalafix w pliku `.scalafix.conf` można dodać/odkomentować linię: +```conf +DisableSyntax.noUniversalEquality = true +``` + +Teraz należy poprawić cały kod zamieniając `==` na `===`. +W przypadku projektu **[resentiment]** są to klasy `CalculatorTest` i `CalculatorIT` + +```scala +package pl.writeonly.re.shared + +import scalaz.Scalaz._ +import utest._ + +object CalculatorTest extends TestSuite { + override val tests: Tests = Tests { + val calculator = new Calculator() + 'addition - { + val addition: (Int, Int) => Int = (x, y) => calculator.add(x, y) + "0 + 0 == 0" - { + assert(addition(0, 0) === 0) + } + "2 + 2 == 4" - { + assert(addition(2, 2) === 4) + } + } + 'multiplication - { + val multiplication: (Int, Int) => Int = (x, y) => calculator.mul(x, y) + "0 + 0 == 0" - { + assert(multiplication(0, 0) === 0) + } + "2 + 2 == 4" - { + assert(multiplication(2, 2) === 4) + } + } + 'less_or_equal - { + val less_or_equal: (Int, Int) => Boolean = (x, y) => calculator.leq(x, y) + "0 <= 2 == true" - { + assert(less_or_equal(0, 2)) + } + "2 <= 0 == false" - { + assert(!less_or_equal(2, 0)) + } + } + } +} +``` + +```scala +package pl.writeonly.re.shared + +import scalaprops.{Property, Scalaprops} +import scalaz.Scalaz._ + +object CalculatorIT extends Scalaprops { + val calculator = new Calculator() + + val addition: (Int, Int) => Int = (x, y) => calculator.add(x, y) + val additionTest = Property.forAll { (a: Int, b: Int) => + addition(a, b) === a + b + } + + val multiplication: (Int, Int) => Int = (x, y) => calculator.mul(x, y) + val multiplicationTest = Property.forAll { (a: Int, b: Int) => + multiplication(a, b) === a * b + } + + val lessOrEqual: (Int, Int) => Boolean = (x, y) => calculator.leq(x, y) + val lessOrEqualTest = Property.forAll { (a: Int, b: Int) => + lessOrEqual(a, b) === (a <= b) + } +} + +``` + +## Podsumowanie +Język Scala posiada kilka mniejszych lub większych błedów projektowych. +Część z nich zostanie poprawiona w nowej wersji kompilatora Dotty. +Jeśli jednak nie chcemy czekać do tego czasu warto się rozejrzeć w internecie, +ponieważ prawdopodobnie istnieją już rozwiązania naszych problemów. +"Universal Equality" jest jednym z problemów, +które w prosty sposób mogą być rozwiązane już dziś. + +[Haskell]: /langs/haskell +[Scala]: /langs/scala + +[Cats]: /libs/cats +[ScalaTest]: /libs/scalatest +[Scalaz]: /libs/scalaz + +[scala native]: /tools/scala-native +[scalafix]: /tools/scalafix +[scala.js]: /tools/scala-js + +[resentiment]: /projects/resentiment + +[klasy typów]: /tags/type-class +[kompilator]: /tags/compiler +[monada]: /tags/monad diff --git a/_collections/_posts/2019-02-13-setxkbmap.md b/_collections/_posts/2019-02-13-setxkbmap.md new file mode 100644 index 00000000..eb1fe957 --- /dev/null +++ b/_collections/_posts/2019-02-13-setxkbmap.md @@ -0,0 +1,74 @@ +--- +title: "setxkbmap - Jak szybko zmienić układ klawiatury z konsoli na Ubuntu?" +author: TheKamilAdam +category: cli +tags: cli +langs: +tools: bash ubuntu +libs: +redirect_from: + - setxkbmap + - cli/setxkbmap + - cli/2019/02/13setxkbmap.html +--- + +Po długiej przerwie prosty artykuł "Jak szybko zmienić układ klawiatury z konsoli na **[Ubuntu]**?". + +## Problem + +Podczas pracy na Xubuntu zainstalowanym na wirtualnej maszynie często zmienia mi się układ klawiatury z polskiej na amerykańską. +Na **[Ubuntu]** można odwrócić ten proces w łatwy sposób za pomocą ikonki na pasku zadań, +jednak już w Xubuntu ta opcja jest ukryta głęboko w trzewiach ustawień systemowych. +Dlatego prościej jest to zrobić z linii poleceń. + +## Rozwiązanie - setxkbmap + +Aby szybko zmienić układ klawiatury, wystarczy zainstalować 'setxkbmap' za pomocą polecenia: +```bash +sudo apt-get install x11-xkb-utils +``` + +Następnie można łatwo zmieniać układ klawiatury za pomocą polecenia: +```bash +setxkbmap pl +``` + +Pomoc można wyświetlić za pomocą polecenia: +```bash +setxkbmap -help +``` + +Pomoc polecenia w wersji 'setxkbmap 1.3.1' : +``` +Usage: setxkbmap [options] [ [ [