Kirjautuminen

Haku

Tehtävät

Keskustelu: Yleinen keskustelu: Eikö C/C++, yksi skripti-"VM" ja DSL:t ole paras mahdollinen stack?

Sivun loppuun

mavavilj [31.12.2023 12:47:33]

#

Eikö C/C++, yksi skripti-"VM" ja DSL:t ole paras mahdollinen stack?

Olen käynyt ohjelmointiteknologioita läpi aika kauan ja on tutkittu Java/JVM, C#, Haskell yms. ja olen tullut lopputulokseen, että "best of all worlds" on:

C/C++ valinnaisilla kirjasto-hardenuksilla (esim. Boehm-GC)
+
yksi skriptikieli-"VM", esimerkiksi JavaScript

Näiden lisäksi kaikki muu tarve ei johdu runtimesta vaan DSL:n (domain-specific language) valinnasta. Jos siis halutaan toiminallisuus, jota näissä ei ole, se tulisi lisätä kirjastona, joka toteutetaan jomman kumman näistä avulla.

Ymmärrän Rust:n ja funktionaalisten kielten edut, mutta minusta ne eivät ole itsenäisiä asioita, vaan niiden toiminnallisuudesta voidaan toteuttaa haluttuja osia aiemmin mainittuun stack:iin. Niillä voi olla arvoa teoreettisena työkaluna.

Käytännön esimerkkejä stack:n eduista:

-selaimet

jalski [31.12.2023 14:18:14]

#

mavavilj kirjoitti:

Ymmärrän Rust:n ja funktionaalisten kielten edut, mutta minusta ne eivät ole itsenäisiä asioita, vaan niiden toiminnallisuudesta voidaan toteuttaa haluttuja osia aiemmin mainittuun stack:iin.

En ihan ymmärrä mitä ajat takaa. Rust pystyy kyllä täysin korvaamaan C/C++:n ohjelmistokehityksessä.

Itse valitsisin ohjelmointityökalut projektin mukaan.

mavavilj [31.12.2023 16:13:26]

#

jalski kirjoitti:

(31.12.2023 14:18:14): ”– –” En ihan ymmärrä mitä ajat takaa. Rust pystyy...

Teoriassa niin, mutta kukaan ei tule kirjoittamaan C/C++ ekosysteemiä uusiksi.

Tarkoittaa, että kirjoitamme esimerkiksi JS:lle "Haskell-minikielen", jos haluamme hyödyntää Haskell:n semantiikkaa.

Niinhän on tehtykin, mutta minusta se johtaa fragmentoitumiseen, koska sitten erikoistuneet kirjastot (esim. 100% Python tai Haskell -kirjastot) on kielillä, joita ei voi käyttää mitenkään järkevästi muista kielistä ja kukaan ei viitsi portata niitä käytettyihin kieliin. Näin on nyt esim. Python:lla, joka ei toimi kaikille alustoille.

Mainitsemani stack:n etu on, että se ei johda koodiin, jota ei pysty interfaceemaan muuten kuin jollain ihme csv/JSON/socket härpäkkeillä, vaan että jokainen käytetty kieli kuuluu jollain tavalla toiseen. Näin ollen niistä pystyy aina ja täydellisesti hyödyntämään toisella kielellä laadittuja kirjastoja.

DSL ratkaisee ongelman sopivuudesta, runtimeissa ei ole kyse sopivuudesta, vaan pelkästä matematiikasta eli siitä miten ison joukon se antaa ja miten hyvin se sopii konekieleen. Runtimen tarkoitus on toteuttaa laajin mahdollinen joukko konstruktioita (esim. C++). Runtime spesialisoidaan haluttuun ongelmaan.

WASM:kin korvaa teoriassa JS:n, mutta vaaditaan JS lataamaan WASM, joten ei käytännössä. Lisäksi C++ + JS socket:n kautta on edelleen nopeampi, yksinkertaisempi ja eristetympi. DSL voisi olla jossain muuallakin, mutta koska JS:n ekosysteemi on suurempi kuin esimerkiksi Haskell:n niin ...

There are only two types of languages.

jalski [31.12.2023 17:10:02]

#

mavavilj kirjoitti:

Teoriassa niin, mutta kukaan ei tule kirjoittamaan C/C++ ekosysteemiä uusiksi.

Niinhän on tehtykin, mutta minusta se johtaa fragmentoitumiseen, koska sitten erikoistuneet kirjastot (esim. 100% Python tai Haskell -kirjastot) on kielillä, joita ei voi käyttää mitenkään järkevästi muista kielistä ja kukaan ei viitsi portata niitä käytettyihin kieliin. Näin on nyt esim. Python:lla, joka ei toimi kaikille alustoille.

Mainitsemani stack:n etu on, että se ei johda koodiin, jota ei pysty interfaceemaan muuten kuin jollain ihme csv/JSON/socket härpäkkeillä, vaan että jokainen käytetty kieli kuuluu jollain tavalla toiseen. Näin ollen niistä pystyy aina ja täydellisesti hyödyntämään toisella kielellä laadittuja kirjastoja.

Useimmissa ohjelmointikielissä on toteutettuna FFI (Foreign Function Interface) jonka avulla kirjoittaa nopeasti pienen wrapperin haluamalleen toiminnallisuudelle C-kutsuttavasta kirjastosta.

mavavilj [31.12.2023 17:15:42]

#

jalski kirjoitti:

(31.12.2023 17:10:02): ”– –” Useimmissa ohjel­moin­ti­kie­lissä on...

Näiden käyttäminen on tulkintani mukaan liian työlästä, jotta riittävän isoja kirjastoja saisi kokonaan koskaan portattua.

Lisäksi monia kirjastoja ei ole kirjoitettu hourglass API -patterniin, joten niitä pitäisi ensin muokata, jotta ne voivat paljastaa "täydellisen" C API:n.

Lisäksi jos FFI API:a käytetään jatkokehitykseen, niin päädytään lopulta samaan ongelmaan, jossa osa koodista on "omalla saarekkeellaan", josta sitä ei voi enää hyödyntää muualle. Ellei jokainen lisäys lisää myös C API:iin. Edelleen ongelmana on saada koodi alustalle, jossa ei ole tukea C API:n toisen puolen kielelle. Monissa käytännön töissä on usein resurssivaje siten, että kaikkia osapuolia ei voi toteuttaa täydellisesti. Tästä on todisteena esimerkiksi Python:n ja Matlab:n yleisyys. Siksi osa oikoo esim. siten, että kirjasto on pääosin Python:lla, koska se oli nopeampaa kirjoittaa sille. Mutta koska kirjasto tuli Python:lla niin jälkeenpäin sen C API:nkin tekeminen on vaikeampaa, koska pitää kelata taaksepäin. Erityisesti, joillekin ohjelmille ei voi laatia ko. wrapperia ellei tunne koko ohjelmistoa.

Jos kirjasto on C:llä, niin se kääntyy melkein jokaiselle alustalle + sille voidaan vielä käyttää DSL:a.

jalski [31.12.2023 17:52:28]

#

mavavilj kirjoitti:

jalski kirjoitti:

(31.12.2023 17:10:02): ”– –” Useimmissa ohjel­moin­ti­kie­lissä on...

Näiden käyttäminen on tulkintani mukaan liian työlästä, jotta riittävän isoja kirjastoja saisi kokonaan koskaan portattua.

Harvemmin jokaisessa projektissa kuitenkaan koko kirjaston toiminnallisuutta tarvitaan? Mikäli haluaa päästä helpolla on C/C++ kuitenkin lähtökohtaisesti jo väärä valinta.

mavavilj [31.12.2023 17:54:30]

#

jalski kirjoitti:

(31.12.2023 17:52:28): ”– –” Harvemmin jokaisessa projektissa kuiten­kaan...

Joo mutta pienen osan irroittaminen voi olla vaikeaa, mikäli projekti ei ole lähtökohtaisesti hyvin modularisoitu. Tällöin "FFI C API" on lähinnä teoreettinen idea. Teoriassa joo, mutta käytännössä ei, jos hostikieli on hyvin yhteensidottua.

Mikäli meillä ei ole muita kieliä kuin C, C++ ja esim. JS, niin voimme edelleen hyödyntää kaikkea koodia siinä kielessä, joka on hostikieli. Joten emme tarvitse erillistä C API:a. Mikäli hostikieli olisi Java, niin meidän tarvitsisi ensin selvittää, miten GC portataan. Mikäli se olisi Python, niin tarvitsisi tyypit. Mikäli se olisi Haskell, niin tarvitsisi tilan.

Mielestäni esimerkiksi Javaa ei koskaan tarkoitettu FFI-kieleksi, vaan itsenäiseksi kieleksi ja C++:n kilpailijaksi. FFI on mukana vain pientä legacya varten, koska muuten kehittäjät alkaisivat valittaa liikaa legacyn porttaamisesta. Java ei kuitenkaan ilmiselvästi ole vahva FFI:n suhteen, koska JNI on työläs käyttää. JS:llä meidän ei tarvitse miettiä FFI:a, koska JS tulkki ja/tai kääntäjä on C/C++:lla.

jalski [01.01.2024 13:12:48]

#

mavavilj kirjoitti:

Mikäli meillä ei ole muita kieliä kuin C, C++ ja esim. JS, niin voimme edelleen hyödyntää kaikkea koodia siinä kielessä, joka on hostikieli. Joten emme tarvitse erillistä C API:a. Mikäli hostikieli olisi Java, niin meidän tarvitsisi ensin selvittää, miten GC portataan. Mikäli se olisi Python, niin tarvitsisi tyypit. Mikäli se olisi Haskell, niin tarvitsisi tilan.

Mielestäni esimerkiksi Javaa ei koskaan tarkoitettu FFI-kieleksi, vaan itsenäiseksi kieleksi ja C++:n kilpailijaksi. FFI on mukana vain pientä legacya varten, koska muuten kehittäjät alkaisivat valittaa liikaa legacyn porttaamisesta. Java ei kuitenkaan ilmiselvästi ole vahva FFI:n suhteen, koska JNI on työläs käyttää. JS:llä meidän ei tarvitse miettiä FFI:a, koska JS tulkki ja/tai kääntäjä on C/C++:lla.

Mikäli hostikieli on Java ei tarvitse portata GC:tä vaan pelkästään tuottaa suoraan Java koodia tai tavukoodia ja ajaa sitä Javan päällä. Java löytyy valmiiksi useimmille alustoille ja toimii myös niistä useimmilla kohtuullisen hyvin. Isoin osa ohjelmointikielistä on toteutettu C/C++:lla. Itse en kuitenkaan näe syytä miksi esimerkiksi Java tai C# ohjelmoija haluaisi kirjoittaa C/C++ koodia ellei olisi aivan pakko.

mavavilj [01.01.2024 16:08:48]

#

jalski kirjoitti:

(01.01.2024 13:12:48): ”– –” Mikäli hostikieli on Java ei tarvitse portata...

Siksi, että tarpeiden muuttuessa Java muuttuu ongelmaksi, kun olisi pitänyt käyttää C/C++ tai pitäisi päästä käyttämään sitä.

Mutta jos tämä olisi tehty JavaScript:llä, niin:

1) siihen olisi mennyt vähemmän aikaa

2) koska siihen meni vähemmän aikaa, niin ongelma olisi havaittu aiemmin

ja

3) voimme helposti ajaa JS:ia kaikilla alustoilla, missä on selain, sen ajan, kun odotamme portausta

Näin ollen koko elinkaarella JS/vast. + "kovatoteutus" tarvittaessa C/C++:lla vie vähemmän resursseja. Ja kun toteutus on, niin siitä on helpompi abstrahoida sekä alas että ylös.

Siksi, että kun tarve C/C++:lle ilmaantuu, niin Java tms. on hyödytön.

Aina voi abstrahoida ylöspäin, mutta ei alaspäin.

Java sulkee tehokkaasti pois esimerkiksi halvat embedded alustat. Niillä voisi kuitenkin pyörittää jotain pientä JS-tulkkia, jonka voi toteuttaa myös ad hoc:sti. Lisäksi JVM on liian samankaltainen kuin selain.

jalski [01.01.2024 17:22:50]

#

mavavilj kirjoitti:

Siksi, että tarpeiden muuttuessa Java muuttuu ongelmaksi, kun olisi pitänyt käyttää C/C++ tai pitäisi päästä käyttämään sitä.

Miksi oletat, että olisi pitänyt tai pitäisi päästä käyttämään C/C++ ? Itse olen yli parikymmentä vuotta tullut hyvin toimeen ilmankin.

Lisäsin kotiautomaatio ohjaimellani pyörivään ohjelmaani tuen pihavalaistuksen ohjaamiseen astronomisen kalenterin avulla. Ohjelmassa nyt 8 säiettä kaikki koordinoituna sulassa sovussa ilman ongelmia, KV-tietokanta, WebSocket tuki, sarjaväylän lukeminen ja syötteen parsiminen... Kaikki 8th:n mukana tulevalla toiminnallisuudella toteutettuna. Mikäli olisin saman toiminnallisuuden lähtenyt toteuttamaan C/C++:lla olisi aikaa minulla kulunut moninkertainen määrä.

Ei ole olemassa mitään absoluuttista parasta työkalua jokaiseen työhön. Mikäli mahdollista niin kannattaa valita se mikä on itselle tutuin ja millä tykkää työskennellä.

mavavilj [01.01.2024 19:18:06]

#

jalski kirjoitti:

mavavilj kirjoitti:

Siksi, että tarpeiden muuttuessa Java muuttuu ongelmaksi, kun olisi pitänyt käyttää C/C++ tai pitäisi päästä käyttämään sitä.

Miksi oletat, että olisi pitänyt tai pitäisi päästä käyttämään C/C++ ? Itse olen yli parikymmentä vuotta tullut hyvin toimeen ilmankin.

...

Ei ole olemassa mitään absoluuttista parasta työkalua jokaiseen työhön. Mikäli mahdollista niin kannattaa valita se mikä on itselle tutuin ja millä tykkää työskennellä.

Koska kuten sanoin, tarpeet muuttuvat. Tulee esimerkiksi projekti, joka on pääasiassa C++, mutta "ahaa tämä ja tuo kirjasto onkin vain Java:lla (no nyt niiden käyttäminen on hankalaa)". Esim. haluat kotiautomaatioosi osan, joka vaatiikin ison numeerisen kirjaston.

Argumenttini onkin, että C/C++ + skriptikieli + DSL:t ovat "best of all worlds" -kompromissi, toisin sanoen se sisältää kaikkien työkalujen parhaat puolet ja kokonaisuudessaan ja pitkällä tähtäimellä täyttää parhaiten kaikki osa-alueet "keskiarvoisesti". Siinä missä kaikki muut häviävät selvästi joissain osa-alueissa.

Metabolix [01.01.2024 19:18:07]

#

Tässä on ilmeisesti jokin oma lähtökohta siihen, mitä projektia ja mille alustoille ollaan tekemässä. Jos jokin ratkaisu olisi yksinkertaisesti paras joka projektiin, miksi sitten muita olisi edes olemassa?

C/C++ ei ole edes mikään kieli, niin kannattaisi ensin päättää, kummasta puhutaan.

C:ssä on niin rajoittuneet ominaisuudet, että jopa olio-ohjelmointi on hieman ärsyttävää purkkaa ja hienommat ominaisuudet eivät ole käytännöllisiä. Tietysti makroista ja funktioista voi luoda uuden kielen, mutta kuka sellaisella haluaa sitten vapaaehtoisesti koodata?

C ja C++ ovat taulukoiden käsittelyssä ja muistinhallinnassa erittäin bugiherkkiä kieliä, minkä johdosta jopa Linuxin ytimeen on tekeillä tuki Rustilla kirjoitettaville ajureille. Näitä kielen perusteita on vaikea korjata kirjastolla tyydyttävästi. Vaikka juuri muistinkäsittelyn turvallisuudesta ei voi "toteuttaa haluttuja osia" C++:aan. Olisi myös ylimielistä ajatella, että muistibugit eivät ikinä koske omaa koodia.

C ja C++ myös vaativat suhteellisen paljon koodia joihinkin asioihin, joihin on muissa kielissä valmiita ratkaisuja. Kirjasto ei korvaa sitä, että jonkin asian voi kirjoittaa lyhyesti ja helppolukuisesti.

Aika on rahaa, joten jos muu kieli sopii ratkaisuun hyvin ja sillä saa nopeammin valmiiksi, ei varmaan ole järkevää lähteä taistelemaan C++:n kanssa. Esimerkiksi kun itse teen tietylle alustalle tiettyyn tarkoitukseen koodia, jota ei ikinä ole tarpeen siirtää vaikka mikrokontrollerille, miksi käyttäisin C:tä (joka pitää kääntää uudestaan esim. eri käyttöjärjestelmää tai akkitehtuuria varten), jos ongelmani ratkeaa helposti Pythonilla (joka on oletuksena asennettu kohdeympäristööni)?

Jos kysymys ei ollutkaan parhaasta valinnasta ohjelmistokehitykseen vaan mahdollisimman monelle alustalle käännettävästä koodista, tietysti sitten C ja C++ ovat vahvoilla. Toivottavasti muistat käyttää aina tarkempia tietotyyppejä (int32_t jne. eikä pelkkä int) ja huomioida BE/LE-muunnokset, ettei tule näistä perusjutuista yllättäviä bugeja eri alustoilla.

mavavilj [01.01.2024 19:20:23]

#

Metabolix kirjoitti:

C ja C++ myös vaativat suhteellisen paljon koodia joihinkin asioihin, joihin on muissa kielissä valmiita ratkaisuja. Kirjasto ei korvaa sitä, että jonkin asian voi kirjoittaa lyhyesti ja helppolukuisesti.

...

C ja C++ ovat taulukoiden käsittelyssä ja muistinhallinnassa erittäin bugiherkkiä kieliä, minkä johdosta jopa Linuxin ytimeen on tekeillä tuki Rustilla kirjoitettaville ajureille. Näitä kielen perusteita on vaikea korjata kirjastolla tyydyttävästi. Olisi ylimielistä ajatella, että bugit eivät ikinä koske omaa koodia.

...

Aika on rahaa, joten jos muu kieli sopii ratkaisuun hyvin ja sillä saa nopeammin valmiiksi, ei varmaan ole järkevää lähteä taistelemaan C++:n kanssa

...

jos ongelmani ratkeaa helposti Pythonilla (joka on oletuksena asennettu kohdeympäristööni)?

Tähän voi luoda omia abstraktioita. Olen käyttänyt juuri yhtä C++:n web server:iä ja minusta sillä kirjoitetaan ~ ihan yhtä monta riviä kuin Java:llakin.

Joo ja bugisuuteenkin voidaan laatia ja käyttää uusia kirjastoja tai jotain DSL:a (kuten SQL).

Aika maksaa rahaa, kun tarpeet joskus muuttuvat.

C++:aan on tullut jo joitain Rust:n ominaisuuksia ja joissain on slide:t, joissa pohditaan sitä, että C++:aan tulisi enemmänkin, koska Rust nähdään "kilpailjana", vaikka C++:n halutaan olevan edelleen "de facto" systeemikieli.

Niin, tuon takia netistä löytyykin kaikkia hienoja kirjastoja, jotka on vain Python:lla tai Matlab:lla, koska tekijä oli liian laiska tekemään hyödynnettävää kirjastoa. Joskus tekijä myös katoaa, jolloin kukaan muu ei osaa myöskään portata sitä. Myös Rust:lle on jo joitain, joita ei voi käyttää esim. Android:lla.

C/C++ + esim. JS siten, että sopivat osat toteutetaan eri osilla tuottaa keskiarvoisesti saman suorituskyvyn kuin esim. JVM:llä, mutta ilman, että tarvitsee luopua korkeiden ja matalien kielien eduista. JVM:ssä kun ei ole kumpaakaan.

Metabolix [01.01.2024 19:42:56]

#

mavavilj kirjoitti:

Joo ja bugisuuteenkin voidaan laatia ja käyttää uusia kirjastoja tai jotain DSL:a (kuten SQL).

Jostain syystä bugisuuteen ei ole tässä C:n 50-vuotisen historian aikana saatu ratkaisua, niin jos se kerran on noin helppoa, voisitko pikaisesti tehdä ja esitellä ratkaisun?

mavavilj kirjoitti:

Netistä löytyykin kaikkia hienoja kirjastoja, jotka on vain Python:lla tai Matlab:lla, koska tekijä oli liian laiska tekemään hyödynnettävää kirjastoa.

Sinua siis harmittaa eri kielillä tehdyt kirjastot. Mikä osa maailman projekteista on kirjastoja? Vihaatko myös muita Python-koodeja, vai lasketaanko ei-kirjaston tekemisessä kieli sitten DSL:ksi (mikä olisi aika teennäistä, jos valinnassa ei ole mitään domainia ja spesifiä)? On paljon tilanteita, joissa ne tarpeet ja tarpeiden muutokset voi hyvin ennakoida, ja silloin C++:lla koodauksen haitat ovat usein isommat kuin hyödyt.

mavavilj [01.01.2024 19:44:11]

#

Metabolix kirjoitti:

Sinua siis harmittaa eri kielillä tehdyt kirjastot. Mikä osa maailman projekteista on kirjastoja? Vihaatko myös muita Python-koodeja, vai lasketaanko ei-kirjaston tekemisessä kieli sitten DSL:ksi (mikä olisi aika teennäistä, jos valinnassa ei ole mitään domainia ja spesifiä)?

Siis koska tällöin tehdään lopulta sama työ > 2 kertaa, kun koodi pitää muuttuvissa tarpeissa portata.

mavavilj [01.01.2024 19:46:36]

#

Metabolix kirjoitti:

Jostain syystä bugisuuteen ei ole tässä C:n 50-vuotisen historian aikana saatu ratkaisua, niin jos se kerran on noin helppoa, voisitko pikaisesti tehdä ja esitellä ratkaisun?

Staattinen analyysi?

Toimii JS:iinkin:

https://github.com/Samsung/SJS

muuskanuikku [02.01.2024 07:00:24]

#

Käyhän nyt ensin koulut loppuun ja mene kokeilemaan noita naiiveja teorioitasi työmaailmaan, niin alkaa silmät aueta... (Ainakin toivottavasti; liian moni kaveri onnistuu jotenkin toistamaan samoja virheitä vuosikymmenet koskaan kehittymättä.)

mavavilj [02.01.2024 13:37:31]

#

Toki tämä stack on sinällään vielä vähän demovaiheessa. Useimmat käyttävät Nodea tms.

Mainitsemani stack:n voi mieltää esimerkiksi Node:ksi ilman JS backend:iä.

Voitte huomioida, että myös Node on saanut kasvavaa kiinnostusta Java:n sijaan. Joten JS ei sinällään ole ongelma. Mutta Node:lla on omat ongelmansa.

Tarkennetaan myös, että stack:ssa C/C++ ei ole tarkoitettu applikaatiokieleksi, vaan toteutuskieleksi. Tämä tarkoittaa, että sen sovelluksessa on tarkoitus olla pedanttinen. Sen tarkoitus ei ole olla "nopea kirjoittaa" (se tehdään DSL:llä).

Ts. stack:ssa mielletään eri osa-alueiksi:

-toteutusympäristö
-tuotantoympäristö

qeijo [03.01.2024 19:41:35]

#

Onkohan 2024 takapuolen renessanssi kun htmx:kin on nousussa. Ei pian tarvita (reakt yök, odotas yöök, yööök <- oksentaa suuhun) yms. enää.

Kun aika on rahaa niin Golang; "oppii" viikossa ja on erittäin käyttökelpoinen esim. rinnakkaisajoon. Rustilla mm. mukavampi virheidenhallinta (ja nopeampi...) mutta vaatii enemmän aikaa oppimiseen ja tekemiseen. Asioita voi tehdä ruosteella monella tavalla jolloin menee helpommin metsään. Vasta väänsin molemmilla kielillä backendit (API yms.) ja mm. rajapinnat chatgipitiin. Lienee bugeja kuten mun koodissa yleensä. Tästä tulis tiukempi jos goolla olisi enumit.

package main

// * Example usage of: chatgpt.ChatCompletion * //

import (
	"fmt"
	"main/chatgpt"
	"os"
)

var apiKey string = os.Getenv("OPENAI_API_KEY")

func main() {

	cc := chatgpt.NewChatCompletion(
		apiKey,
		chatgpt.ModelGPT4,
		100,
		chatgpt.HTTPRequestHandler,
		&chatgpt.JsonMarshalHandler{},
	)

	cc.AddMessage(chatgpt.ChatGPTRoleAssistant, "Olet kiltti avustaja")
	cc.AddMessage(chatgpt.ChatGPTRoleUser, "Kuinka paljon on liikaa?")

	response, err := cc.HandleRequest()
	if err != nil {
		fmt.Println("Chatgpt return a error:", err)
		return
	}

	// Do something with the response
	fmt.Println(response.Choices[0].Message.Content)
}
package chatgpt

// * ChatCompletion Logic * //

const (
	endpoint = "https://api.openai.com/v1/chat/completions"

	ModelGPT4       ChatModel = "gpt-4"
	ModelGPT35Turbo ChatModel = "gpt-3.5-turbo"
	// TODO: Add more models

	ChatGPTRoleUser      ChatGPTRole = "user"
	ChatGPTRoleSystem    ChatGPTRole = "system"
	ChatGPTRoleAssistant ChatGPTRole = "assistant"
)

type ChatModel string
type ChatGPTRole string

// * ChatCompletion *//
type ChatCompletion struct {
	apikey   string
	rh       ChatGPTRequestHandler
	jt       JsonTranslatorHandler
	request  *ChatCompletionRequest
	response *ChatCompletionResponse
}

func NewChatCompletion(
	apikey string,
	model ChatModel,
	maxtokens int,
	requestHandler ChatGPTRequestHandler,
	jsonTranslator JsonTranslatorHandler) *ChatCompletion {

	return &ChatCompletion{
		apikey: apikey,
		rh:     requestHandler,
		jt:     jsonTranslator,
		request: &ChatCompletionRequest{
			Model:     model,
			MaxTokens: maxtokens,
		},
	}
}

func (c *ChatCompletion) AddMessage(role ChatGPTRole, content string) error {
	// TODO: Add validation of role and content
	c.request.Messages = append(c.request.Messages, Message{
		Role:    role,
		Content: content,
	})
	return nil
}

func (c *ChatCompletion) ClearMessages() {
	c.request.Messages = []Message{}
}

func (c *ChatCompletion) HandleRequest() (*ChatCompletionResponse, error) {

	request, err := c.jt.Marshal(c.request)
	if err != nil {
		return nil, err
	}
	response, err := c.rh(endpoint, c.apikey, request)
	if err != nil {
		return nil, err
	}

	var ccr ChatCompletionResponse
	if err := c.jt.Unmarshal(response, &ccr); err != nil {
		return nil, err
	}

	c.response = &ccr
	return c.response, nil
}
package chatgpt

// * Contains types and interfaces * //

// Function interface for ChatCompletion Request Handler
type ChatGPTRequestHandler func(url string, apikey string, requestModel []byte) ([]byte, error)

// Interface for Json Translator Handler
type JsonTranslatorHandler interface {
	Marshal(v interface{}) ([]byte, error)
	Unmarshal(data []byte, v interface{}) error
}

// Request structs
type ChatCompletionRequest struct {
	Messages    []Message `json:"messages"`
	MaxTokens   int       `json:"max_tokens"`
	Model       ChatModel `json:"model"`
	Stop        []string  `json:"stop,omitempty"`
	TopP        float64   `json:"top_p,omitempty"`
	Temperature float64   `json:"temperature,omitempty"`
}
type Message struct {
	Role    ChatGPTRole `json:"role"`
	Content string      `json:"content"`
}

// Response structs
type ChatCompletionResponse struct {
	Created           int      `json:"created"`
	Model             string   `json:"model"`
	Choices           []Choice `json:"choices"`
	Usage             Usage    `json:"usage"`
	SystemFingerprint *string  `json:"system_fingerprint"`
}
type Choice struct {
	Index        int     `json:"index"`
	Message      Message `json:"message"`
	Logprobs     *string `json:"logprobs"`
	FinishReason string  `json:"finish_reason"`
}
type Usage struct {
	PromptTokens     int `json:"prompt_tokens"`
	CompletionTokens int `json:"completion_tokens"`
	TotalTokens      int `json:"total_tokens"`
}
package chatgpt

// * Contains implementations for interfaces defined in types.go * //

import (
	"bytes"
	"encoding/json"
	"errors"
	"io"
	"net/http"
)

func HTTPRequestHandler(url string, apikey string, requestModel []byte) ([]byte, error) {

	req, err := http.NewRequest("POST", url, bytes.NewBuffer(requestModel))
	if err != nil {
		// * Most likely a configuration error; however we let the caller handle this.
		return nil, err
	}

	req.Header.Set("Authorization", "Bearer "+apikey)
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{}
	//	Timeout: time.Second * 15,
	//}

	resp, err := (client).Do(req)
	if err != nil {
		//* We assume network:ish error, and that the request was not successful.
		return nil, err
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		// * The request was successful, but the response body could not be read; however we let the caller handle this.
		return nil, err
	}
	if resp.StatusCode != 200 {
		// * The request was successful, but the response status code was not 200.
		return nil, errors.New("We wanted a '200 OK'. However, the server returned status code: " + resp.Status + "\nAnd body:\n" + string(body) + "\n)")
	}
	return body, nil
}

type JsonMarshalHandler struct{}

func (jt *JsonMarshalHandler) Marshal(v interface{}) ([]byte, error) {
	return json.Marshal(v)
}
func (jt *JsonMarshalHandler) Unmarshal(data []byte, v interface{}) error {

	return json.Unmarshal(data, v)
}

qeijo [03.01.2024 19:49:42]

#

Tässä vielä jokin aikojen alussa tehty osin kesken jäännyt pätkä missä käy mielestäni go:n rinnakkaisajo hyvin ilmi (saa haukkua kuten täällä yleensä.)

package main

// * Example of usage * //

import (
	"fmt"
	"log"
	"main/goports"
	"os"
)

func main() {

	// TODO: Create Adapter for CLI-arguments to Inject into goports.Scan()

	if len(os.Args) < 3 {
		fmt.Println("Usage: go run scanner.go <IP> <Port/PortRange>")
		fmt.Println("Example: go run scanner.go 127.0.0.1 80")
		fmt.Println("Example: go run scanner.go 127.0.0.1 1-20000")
		return
	}

	ip, err := goports.ParseIP(os.Args[1])
	if err != nil {
		log.Fatal(err.Error())
	}

	port_begin, port_end, err := goports.ParsePorts(os.Args[2])
	if err != nil {
		log.Fatal(err.Error())
	}

	goports.Scan(ip, port_begin, port_end)
}
package goports

// * All there is is here * //

import (
	"errors"
	"fmt"
	"net"
	"os"
	"strconv"
	"strings"
	"sync"
)

const max_routines = 50

func Scan(ip net.IP, port_begin int, port_end int) {

	var wg sync.WaitGroup
	sp := make(chan struct{}, max_routines)
	defer close(sp)

	ip_str := ip.String()
	for port := port_begin; port <= port_end; port++ {
		wg.Add(1)
		sp <- struct{}{}
		go func(port int) {
			defer wg.Done()
			if conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", ip_str, port)); err == nil {
				defer conn.Close()
				fmt.Printf("Port %d is open\n", port)
			}
			<-sp
		}(port)
	}
	wg.Wait()
}

func ParseIP(ip_str string) (net.IP, error) {

	if ip := net.ParseIP(os.Args[1]); ip != nil {
		return ip, nil
	}
	return nil, errors.New("invalid IP address")
}

func ParsePorts(ports_str string) (int, int, error) {

	if strings.Contains(ports_str, "-") {

// * Still unsafe, check indexs * //

		var (
			port_range            = strings.Split(ports_str, "-")
			port_begin, err_begin = strconv.Atoi(port_range[0])
			port_end, err_end     = strconv.Atoi(port_range[1])
		)

		if err_begin != nil || err_end != nil {
			return 0, 0, errors.New("invalid port range")
		}

		return port_begin, port_end, nil
	}

	port, err := strconv.Atoi(ports_str)
	if err != nil {
		return 0, 0, errors.New("invalid port number")
	}

	return port, port, nil
}

qeijo [04.01.2024 03:04:00]

#

Luin lopulta ketjun ja tuli mieleen yksi tarina,

Eräänä aamuna, kun aamukaste vielä kimmelsi ikkunalasilla, mavavilj lähti kylästään suureen kaupunkiin etsimään viisautta. Hän oli kuullut tarinoita valtavasta tornista, jossa tiedon kerrokset oli pinottu toistensa päälle kuin kirjat hyllyssä. Tämä torni, sanottiin, oli täynnä vastauksia elämän suurimpiin kysymyksiin.

Kun hän saapui kaupunkiin, hän näki tornin kohoavan ylväästi taivaalle. Ihmiset kulkivat sen ohi kiireisinä ja vakavina, mutta mavjava, joka ei tiennyt, miten torniin pääsee, päätti kiivetä ulkoseinää pitkin. Hän ajatteli, että jos hän vain pääsisi tarpeeksi korkealle, hän voisi kurkistaa sisään ja nähdä kaiken tiedon, joka oli pinottu stackiksi - niin hän oli kuullut ihmisten tornia kutsuvan.

Kun hän kiipesi, ohikulkijat nauroivat ja huutelivat hänelle: "mavalnyi, torniin mennään sisäkautta!" Mutta hän ei kuunnellut. Hän uskoi, että hänen ainutlaatuinen reittinsä olisi se, joka johtaisi hänet suurimpien oivallusten äärelle.

Lopulta, voimansa lopussa ja sormensa arat, hän tavoitti ikkunan ja kurkisti sisään. Siellä hän näki lukemattomia ihmisiä ahertamassa, silmät kiinni tiedossa ja kädet täynnä papereita. Tieto oli niin tiiviisti pinottu, että se näytti olevan valmis romahtamaan millä hetkellä tahansa.

Silloin majava tajusi: kaiken tämän tiedon ja viisauden stack oli niin hauras ja epävakaa, että yksi väärä liike voisi kaataa koko tornin. Hän ymmärsi, että todellinen viisaus ei piile tietojen kerrostamisessa vaan niiden ymmärtämisessä ja soveltamisessa.

Hymyillen ja viisastuneena hän laskeutui alas ja kulki tornin ovesta sisään kuten kaikki muutkin. Ja vaikka häntä vieläkin kutsuttiin idiootiksi, hän tiesi, että oli oppinut jotakin, mitä tornin sisällä olevat eivät ehkä koskaan ymmärtäisi: että elämä ja tieto ovat kuin stack, joka voi kaatua milloin tahansa, ja viisainta on kulkea varoen, ymmärtäen ja nöyränä.

mavavilj [04.01.2024 11:47:52]

#

Osassa vastauksissa rajoitutaan siihen, että jos sovellus tehdään vain kerran, ja sillä ei ole muita hyödyntäjiä esim. muihin kieliin.

muuskanuikku [04.01.2024 14:23:48]

#

mavavilj kirjoitti:

Osassa vastauksissa rajoitutaan siihen, että jos sovellus tehdään vain kerran, ja sillä ei ole muita hyödyntäjiä esim. muihin kieliin.

Sinä taas et ymmärrä sitä, että jos koodari tekee esimerkiksi kirjaston Matlabille ja hyödyntää koodissaan runsaasti Matlabin ominaisuuksia, niin ei sellaista kirjastoa voi edes kirjoittaa C-kielellä, koska C:stä puuttuvat ne korkeamman tason abstraktiot, jotka Matlabista löytyvät. Tämä voi peräti olla syykin siihen, miksi kirjasto on alun perinkin kirjoitettu "Matlabilla" eikä jollain geneerisellä kielellä.

mavavilj [04.01.2024 14:41:18]

#

muuskanuikku kirjoitti:

(04.01.2024 14:23:48): ”– –” Sinä taas et ymmärrä sitä, että jos koodari...

Miksi näitä abstraktioita ei voi toteuttaa muualle?

qeijo [04.01.2024 14:58:18]

#

Kokemukseni mukaan kannattaa olla iloinen jos on jotain tekemistä ja jotakin kiinnostaa sinun tekelesi. Ensimmäinen versio kannattaa tehdä niin että se heitetään pois kun ongelma on ratkaistu ja tehdään toinen, sitten kolmas. Joillakin on enemmän servereitä kuin asiakkaita.

PS. Suomen kieli on minun kolmas kieli.

muuskanuikku [04.01.2024 15:04:46]

#

mavavilj kirjoitti:

muuskanuikku kirjoitti:

(04.01.2024 14:23:48): ”– –” Sinä taas et ymmärrä sitä, että jos koodari...

Miksi näitä abstraktioita ei voi toteuttaa muualle?

Koska Matlabin ominaisuudet ovat käytössä vain Matlabissa. Jos kyseiset asiat olisi helppo kirjoittaa uusiksi tuosta vain about kenen tahansa toimesta, niin Matlabilla olisi varmasti useita täysin ilmaisia kilpailijoita.

Yleensäkin jos haluaa saada jotain valmiiksi, niin koodia ei lähdetä kirjoittamaan tyhjän päälle vaan käytetään sopivia kirjastoja.

mavavilj [04.01.2024 16:02:02]

#

muuskanuikku kirjoitti:

(04.01.2024 15:04:46): ”– –” Koska Matlabin ominaisuudet ovat käytössä vain...

Tavallaan sille onkin. Esim. GNU GSL.

jalski [04.01.2024 18:15:22]

#

mavavilj kirjoitti:

Osassa vastauksissa rajoitutaan siihen, että jos sovellus tehdään vain kerran, ja sillä ei ole muita hyödyntäjiä esim. muihin kieliin.

Toisaalta voisit miettiä asian niinkin päin, että on ajan ja resurssien haaskausta miettiä ohjelmistokehitystä siltä kannalta, että jokaisen ohjelman pitäisi toimia jokaisella mahdollisella alustalla. Miksi mielestäsi aina pitäisi miettiä muita hyödyntäjiä?

mavavilj [06.01.2024 10:15:12]

#

jalski kirjoitti:

(04.01.2024 18:15:22): ”– –” Toisaalta voisit miettiä asian niinkin päin...

Voi olla. Lopulta monet alustat kuitenkin haluavat saman toiminallisuuden.

En ole esimerkiksi vakuuttunut siitä, että Java/Kotlin/Objective-C/Swift mobiilualustoille on tehokkaampaa kuin, että niille jaettaisiin sama C/C++ kuin muilla alustoilla.

Toki, jos ohjelmisto on vain mobiilialustalle, niin tällöin sen oma työkalu on tehokkaampi.

Jos tätä sovelletaan Matlab:iin, niin tottakai Matlab on myös tehokkaampi niiden keskuudessa, jotka käyttävät _vain_ Matlab:ia.

Ehkä monialustakehittäjät ovatkin minoriteetti?

jalski [06.01.2024 16:37:03]

#

mavavilj kirjoitti:

En ole esimerkiksi vakuuttunut siitä, että Java/Kotlin/Objective-C/Swift mobiilualustoille on tehokkaampaa kuin, että niille jaettaisiin sama C/C++ kuin muilla alustoilla.

Ehkä monialustakehittäjät ovatkin minoriteetti?

Monesti kehittäjät tuntuvat keskittyvän joko Windows ja Android ekosysteemiin tai Mac ekosysteemiin. Varmasti Mac alustalla Swift ja SwiftUI on kehittäjän kannalta parempi vaihtoehto kuin C++.

mavavilj [06.01.2024 16:41:40]

#

jalski kirjoitti:

(06.01.2024 16:37:03): ”– –” Monesti kehittäjät tuntuvat keskittyvän joko Windows ja Android ekosysteemiin tai Mac ekosysteemiin.

Tarkoitat, että eri henkilöt ovat erikoistuneet eri teknologioihin? No onhan sekin mahdollista.

Mutta en näe Windows:lla kauheasti Java-ohjelmia, ja mitä varten C# sitten on?

Sen sijaan leikin juuri Mozilla Web API:lla ja sama koodi pyörii kaikkialla selaimessa.

qeijo [06.01.2024 17:06:58]

#

WASM? Mitä ollaan mieltä? Onko ikuinen tulevaisuus vai joskus todellisuutta? Rustilla front, back, middle, side -waret.

mavavilj [06.01.2024 17:10:10]

#

qeijo kirjoitti:

WASM? Mitä ollaan mieltä? Onko ikuinen tulevaisuus vai joskus todellisuutta? Rustilla front, back, middle, side -waret.

Minusta WASM on turha, koska huomasin, että WebSocket/vast. antaa paremman suorituskyvyn ja mitään ei tarvitse muuttaa. Tulkitsin, että WASM oli suunnattu pelkästään web-kehittäjille eli sellaisille, jotka eivät halua kirjoittaa lainkaan natiivikoodia, mutta jotka haluavat sieltä kirjastoja. Jos omaa backend-koodarin, niin en näe miten WASM:sta on mitään iloa.

Toisaalta se tukee tässä threadin alussa ollutta ideaa siitä, että selain on hyvä jakelualusta.

feenix [06.01.2024 18:45:59]

#

mavavilj kirjoitti:

Minusta WASM on turha, koska huomasin, että WebSocket/vast. antaa paremman suorituskyvyn ja mitään ei tarvitse muuttaa. Tulkitsin, että WASM oli suunnattu pelkästään web-kehittäjille eli sellaisille, jotka eivät halua kirjoittaa lainkaan natiivikoodia, mutta jotka haluavat sieltä kirjastoja. Jos omaa backend-koodarin, niin en näe miten WASM:sta on mitään iloa.

Toisaalta se tukee tässä threadin alussa ollutta ideaa siitä, että selain on hyvä jakelualusta.

Fronttialusta koodin ajamiseen on turha, koska voit... käyttää WebSocketeja? Miten ne tekevät saman asian? Mihin niitä käytät? Miten teet WebSocketeilla käyttöliittymän? Tai laskennan selainpäässä? Tai validoinnin? Tai... mitään?

Ja luuletko oikeasti että WASM on backendiin suunnattu?

Nyt ihan oikeasti jos et trollaa niin käypä edes lukemassa perusteet ohjelmoinnista, sitten perusteet WASMista, ja vähän muita perusteita. Tuntuu olevan aika hukassa perusteet että voisi niistä mitään puhua oikeasti.

mavavilj [06.01.2024 19:57:30]

#

feenix kirjoitti:

mavavilj kirjoitti:

Minusta WASM on turha, koska huomasin, että WebSocket/vast. antaa paremman suorituskyvyn ja mitään ei tarvitse muuttaa. Tulkitsin, että WASM oli suunnattu pelkästään web-kehittäjille eli sellaisille, jotka eivät halua kirjoittaa lainkaan natiivikoodia, mutta jotka haluavat sieltä kirjastoja. Jos omaa backend-koodarin, niin en näe miten WASM:sta on mitään iloa.

Toisaalta se tukee tässä threadin alussa ollutta ideaa siitä, että selain on hyvä jakelualusta.

Fronttialusta koodin ajamiseen on turha, koska voit... käyttää WebSocketeja? Miten ne tekevät saman asian? Mihin niitä käytät? Miten teet WebSocketeilla käyttöliittymän? Tai laskennan selainpäässä? Tai validoinnin? Tai... mitään?

Siten, jos JS riittää piirtämiseen yms., niin WASM:ia ei tarvita mihinkään.

Ja luuletko oikeasti että WASM on backendiin suunnattu?

Ei vaan tarkoitin, että WASM:n eräs puoli on mahdollistaa natiivikoodin tuominen selaimeen. Kuitenkin WebSocket:eilla natiivikoodi voidaan edelleen ajaa sellaisenaan ja frontend sellaisenaan, ja siksi natiivikoodia ei tarvitse kääntää WASM:ksi, kun riittää vaan siirrellä tarvittava data WebSocket:lla.

qeijo [07.01.2024 13:33:46]

#

Onko eri konsepti suorittaa tehokkaasti binääriä asiakkaan päässä, kuin tunkea JSON:ia WebSocketin kautta asiakkaalle?

mavavilj [07.01.2024 15:58:56]

#

qeijo kirjoitti:

Onko eri konsepti suorittaa tehokkaasti binääriä asiakkaan päässä, kuin tunkea JSON:ia WebSocketin kautta asiakkaalle?

Spekuloin, että ei, koska suoritetaan laskenta backend:ssä ja siirretään frontendiin niin vähän dataa, että JS vs WASM erolla ei ole käytännön väliä. Sanoin "spekuloin", koska minulla ei ole käytännön esimerkkejä tästä.

Mutta raakadata sanoo:

https://nickb.dev/blog/wasm-and-native-node-module-performance-comparison/bench-node-wasm.c866c85f703cd4f42f0f84c27f­bedd0­ce4­fedf65201b72dd51d­be30c6550a­e86.png

Joten karkeasti kai jos natiivi:lla on 220/140=n. 57% enemmän suorituskykyä, niin WASM:n ja JS:n välillä voidaan hävitä saman verran eikä eroa havaita?

Ja tässähttps://ik.imagekit.io/serenity/ByteofDev/Blog_Content_Images/wasm_benchmarks ero on < 50%.

jalski [07.01.2024 16:15:16]

#

mavavilj kirjoitti:

Spekuloin, että ei, koska suoritetaan laskenta backend:ssä ja siirretään frontendiin niin vähän dataa, että JS vs WASM erolla ei ole käytännön väliä. Sanoin "spekuloin", koska minulla ei ole käytännön esimerkkejä tästä.

Eikö mielestäsi frontend toteutukseen voi käyttää muutakin kuin JS tai WASM pohjaista ratkaisua? Itse toteutan omaan kotiautomaatio ohjelmistooni kaiken 8th:lla. Tähän kuuluu siis viestienvälitys palvelin, ohjaimella pyörivä ohjaussofta ja työpöydällä sekä mobiilialustoilla toimiva hallintasovellus.

mavavilj [07.01.2024 18:49:49]

#

jalski kirjoitti:

(07.01.2024 16:15:16): ”– –” Eikö mielestäsi frontend toteutukseen voi...

Voisi, mutta Java Applet:it kuoletettiin.

jalski [07.01.2024 19:07:05]

#

mavavilj kirjoitti:

jalski kirjoitti:

(07.01.2024 16:15:16): ”– –” Eikö mielestäsi frontend toteutukseen voi...

Voisi, mutta Java Applet:it kuoletettiin.

Tarvitseeko välttämättä olla selainpohjainen ratkaisu?

mavavilj [07.01.2024 19:38:07]

#

jalski kirjoitti:

mavavilj kirjoitti:

jalski kirjoitti:

(07.01.2024 16:15:16): ”– –” Eikö mielestäsi frontend toteutukseen voi...

Voisi, mutta Java Applet:it kuoletettiin.

Tarvitseeko välttämättä olla selainpohjainen ratkaisu?

Riippuu käyttäjäkunnasta. Osa ei halua asentaa ohjelmia.

mavavilj [10.01.2024 11:18:47]

#

Niin ja siis voisi, koska Kotlin Android SDK:lla ei ole kovin paljoa monimutkaisempaa kuin HTML/CSS/JS, mutta ongelma on, että mielestäni se ei ole kovin tuettu muilla alustoilla, joten vaikka se toimisi, niin se ei ole standardi tapa toteuttaa ohjelmia esim. Windowsille.

Vertaillen näemme luultavasti enemmän Electron (JS) -sovelluksia kuin Kotlin -sovelluksia pöytäkoneilla. Ehkä myös Flutter -sovelluksia. Jotkut ovat yrittäneet Flutter -frontend:iä myös vaativille ohjelmistoille, koska heidänkin argumentti on ollut, että suorituskykyero johonkin C++ GUI:hin on mitätön käytännössä.

mavavilj [12.01.2024 10:13:36]

#

Niin, olen lukenut netistä nyt Kotlin MP:sta ja vaikuttaa siltä, että sekään ei ole ihan suoraviivainen juttu, koska se vaatii edelleen alustojen natiivityökaluja.

Tuntuu, että olisi järkevämpää kirjoittaa C/C++ -moduuleita "shared moduleiksi". Se on kuitenkin Android:llakin käsittääkseni alin nimittäjä, koska Android:n toteutus C++:sta ei ole täydellinen.

Kumma, jos kukaan ei ole keksinyt tehdä jotain universaali Jetpack Compose:a.

Koska GUI on usein/aina yksisäikeinen, niin JavaScript on ihan luonteva juttu.

jalski [12.01.2024 11:04:06]

#

mavavilj kirjoitti:

(12.01.2024 10:13:36): Niin, olen lukenut netistä nyt Kotlin MP:sta ja...

Kyllähän kirjastot kannattaa kirjoittaa sillä ohjelmointikielellä mitä käyttää toteutukseen. Electron pohjaiset ohjelmat ovat ovat muuten pahimmillaan tietoturvariski.

mavavilj [12.01.2024 11:45:56]

#

Kumoan tässä nyt sitten oman teesini, koska SDL:n porttaus Android:lle tarkoittaa, että on olemassa (natiivi) rajapinta, joka on parempi kuin JS selainmoottorissa. Eli natiivi OpenGL (ES) yms.

JS oli kyllä hyödyllinen prototyypin tekemiseen. Ehkä sillä on vielä paikkansa myös silloin kun lopputuote halutaan nopeasti ulos.

Tavallaan argumenttini siis säilyi.

mavavilj [16.01.2024 12:08:14]

#

Heitetäänpä vielä lisää bensaa tuleen:

Mielestäni Flutter:iin kehitetty Dart (https://en.wikipedia.org/wiki/Dart_(programming_language)) omaa pääosin tässä ketjussa esitetyt edut C/C++:n tason ja JavaScript:n välistä. Se on nopeampi ja staattisempi kuin JS, mutta dynaamisempi kuin C/C++.

Flutter on myös suosittu nimenomaan kompromissina tuohon väliin.

mavavilj [16.02.2024 17:59:30]

#

En tiedä, onko sattumaa, mutta Objective-C on C:n ja Smalltalk:n (VM-kieli) synergia.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta