tag:blogger.com,1999:blog-63378669780931572472024-03-17T23:17:03.320-03:00Emanuel Goette, alias CrespoCambiaríamos el mundo pero no tenemos el código fuente.emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.comBlogger3104125tag:blogger.com,1999:blog-6337866978093157247.post-19106789612594577682024-03-17T23:16:00.000-03:002024-03-17T23:16:30.172-03:00Anotaciones de tipo en gleam<p><br /></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7qiUUY58gf7kto7olOYPc4OG4z3C6Oyu0ojWWQBlnGsWk9xT53dTOVi8oINMtgts7xHOiD8BFvDVU6J8YZ8q-hewopwTJhXAY2lArZc2_EnK9ljfwSiHMPDwbma2r-A0XNg7ZXx0FBWJOk7QIaV7z8NILH9uxRE3sy6pz_a0EQU2ulKigAbg6lsApSzs/s225/Gleam.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="225" data-original-width="225" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7qiUUY58gf7kto7olOYPc4OG4z3C6Oyu0ojWWQBlnGsWk9xT53dTOVi8oINMtgts7xHOiD8BFvDVU6J8YZ8q-hewopwTJhXAY2lArZc2_EnK9ljfwSiHMPDwbma2r-A0XNg7ZXx0FBWJOk7QIaV7z8NILH9uxRE3sy6pz_a0EQU2ulKigAbg6lsApSzs/s1600/Gleam.png" width="225" /></a></div><br />pub fn main() {<p></p><p> let _name: String = "Gleam"</p><p> let _is_cool: Bool = True</p><p> let _version: Int = 1</p><p>}</p><div><br /></div><p>let se pueden escribir con una anotación de tipo después del nombre.</p><p>Las anotaciones de tipo pueden ser útiles para fines de documentación, pero no cambian la forma en que Gleam verifica el código más allá de garantizar que la anotación sea correcta.</p><p>Normalmente, el código Gleam no tendrá anotaciones de tipo para las asignaciones.</p><p><br /></p>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-13516803717874936122024-03-16T18:13:00.001-03:002024-03-16T18:13:01.841-03:00Comprensiones binarias en Erlang<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqruSbgdk7pXnzqtfkZ5JZDV-b1FtVfPNRIqUVRykK2hNQZEYvtlSVt2XX5WM-jEySPUyr-dksxprVDsHd2jdiOF9GHKFMJJ6zrUxjOf4PGzzn8b5vJL3Kj3_d37XZ1IVOUdPRHIoSPcqIH55jpCxR2Nxzj003_BasMo93lg6h5aiW-8qnRlXGUYAQq5M/s132/erlang.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="112" data-original-width="132" height="112" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqruSbgdk7pXnzqtfkZ5JZDV-b1FtVfPNRIqUVRykK2hNQZEYvtlSVt2XX5WM-jEySPUyr-dksxprVDsHd2jdiOF9GHKFMJJ6zrUxjOf4PGzzn8b5vJL3Kj3_d37XZ1IVOUdPRHIoSPcqIH55jpCxR2Nxzj003_BasMo93lg6h5aiW-8qnRlXGUYAQq5M/s1600/erlang.png" width="132" /></a></div><br /> Las comprensiones binarias son para la sintaxis de bits lo que las listas por comprensión son para las listas: una forma de hacer que el código sea breve y conciso. Son relativamente nuevos en el mundo de Erlang como lo fueron en revisiones anteriores de Erlang, pero requirieron un módulo que los implementara para usar un indicador de compilación especial para poder funcionar. Desde las revisiones R13B (las que se usan aquí), se han convertido en estándar y se pueden usar en cualquier lugar, incluido el shell:<p></p><p><br /></p><p>1> [ X || <<X>> <= <<1,2,3,4,5>>, X rem 2 == 0]. </p><p>[2,4]</p><p><br /></p><p>El único cambio en la sintaxis con respecto a las listas por comprensión normales es <- que se convirtió en <= y usa binarios (<<>>) en lugar de listas ([]). Anteriormente vimos un ejemplo en el que había un valor binario de muchos píxeles en el que utilizamos la coincidencia de patrones para capturar los valores RGB de cada píxel. Estaba bien, pero en estructuras más grandes, posiblemente sería más difícil de leer y mantener. El mismo ejercicio se puede hacer con una comprensión binaria de una línea, que es mucho más clara:</p><p><br /></p><p>2> Pixels = <<213,45,132,64,76,32,76,0,0,234,32,15>>.</p><p><<213,45,132,64,76,32,76,0,0,234,32,15>></p><p>3> RGB = [ {R,G,B} || <<R:8,G:8,B:8>> <= Pixels ].</p><p>[{213,45,132},{64,76,32},{76,0,0},{234,32,15}]</p><p><br /></p><p>Cambiando <- a <= usemos un flujo binario como generador. La comprensión binaria completa básicamente cambió los datos binarios a números enteros dentro de tuplas. Existe otra sintaxis de comprensión binaria que le permite hacer exactamente lo contrario:</p><p><br /></p><p>4> << <<R:8, G:8, B:8>> || {R,G,B} <- RGB >>.</p><p><<213,45,132,64,76,32,76,0,0,234,32,15>></p><p><br /></p><p>Los elementos del binario resultante requieren un tamaño claramente definido si el generador devolvió binarios:</p><p><br /></p><p>5> << <<Bin>> || Bin <- [<<3,7,5,4,7>>] >>.</p><p>** exception error: bad argument</p><p>6> << <<Bin/binary>> || Bin <- [<<3,7,5,4,7>>] >>. </p><p><<3,7,5,4,7>></p><p><br /></p><p>También es posible tener una comprensión binaria con un generador binario, siempre que se respete la regla de tamaño fijo anterior:</p><p><br /></p><p>7> << <<(X+1)/integer>> || <<X>> <= <<3,7,5,4,7>> >>.</p><p><<4,8,6,5,8>></p><p><br /></p>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-22743366558903385832024-03-13T02:13:00.000-03:002024-03-13T02:13:18.886-03:00Discard patterns o underscore o guion bajo en Gleam<p> </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHslfb5FlL9BdcWKGqObyMMvhMoTVo8-dyO34fC9sLLifsNORdmzTbLIaa8rKly2MIAOdVEN1T2nKNd2zgBUh2MUhhuZxdcoGat7q9RpkiLF69PDRnAMcZpanhThvr8Xf-86k8yC5G-PuYR7cV13mVo7agSeb_7f2c6MJrbw0nZsiJBn_yhwZVPvToA28/s225/Gleam.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="225" data-original-width="225" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHslfb5FlL9BdcWKGqObyMMvhMoTVo8-dyO34fC9sLLifsNORdmzTbLIaa8rKly2MIAOdVEN1T2nKNd2zgBUh2MUhhuZxdcoGat7q9RpkiLF69PDRnAMcZpanhThvr8Xf-86k8yC5G-PuYR7cV13mVo7agSeb_7f2c6MJrbw0nZsiJBn_yhwZVPvToA28/s1600/Gleam.png" width="225" /></a></div><br />pub fn main() {<p></p><p> // This variable is never used</p><p> let _score = 1000</p><p>}</p><div><div>Si se asigna una variable pero no se utiliza, Gleam emitirá una advertencia.</div><div><br /></div><div>Si se pretende que una variable no se utilice, el nombre puede tener como prefijo un guión bajo, silenciando la advertencia.</div></div><div><br /></div><div>Si al ejemplo le quitamos el _ vamos a obtener el siguiente warning : </div><div><br /></div><div><div>warning: Unused variable</div><div> ┌─ /src/main.gleam:3:7</div><div> │</div><div> │ let score = 1000</div><div> │ ^^^^^ This variable is never used</div><div><br /></div><div>Hint: You can ignore it with an underscore: `_score`.</div></div><div><br /></div><div><br /></div>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-87664243473013498002024-03-09T14:35:00.000-03:002024-03-09T14:35:01.480-03:00Otro ejemplo de Stl de C++<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj64t9krjd88PA6sRGYRqOCoWxQNIZKSU5MQQILvlFNhmSgmiXm_hAFAWBxBdLQNRXoqHduBdBhEMJg5VT1ZdI2u-1Rxoqe7kqD6Vbsmf1ASJzoR5KXELUApON44XugTeRsez2R2P4UIwKoiXTD-isYRPGjqonp2txTEJUlsrh1658LTO2zve4KwElMLKY/s1349/cpp.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1349" data-original-width="1200" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj64t9krjd88PA6sRGYRqOCoWxQNIZKSU5MQQILvlFNhmSgmiXm_hAFAWBxBdLQNRXoqHduBdBhEMJg5VT1ZdI2u-1Rxoqe7kqD6Vbsmf1ASJzoR5KXELUApON44XugTeRsez2R2P4UIwKoiXTD-isYRPGjqonp2txTEJUlsrh1658LTO2zve4KwElMLKY/s320/cpp.png" width="285" /></a></div><br />Escribamos un programa que muestre las palabras y la cantidad de veces que aparecen dentro de un archivo de texto. <p></p><p>vector<string> v;</p><p>map<string, int> m;</p><p>copy(istream_iterator<string>(ifstream("words.txt")), istream_iterator<string>(), back_inserter(v));</p><p>for (auto vi = v.begin(); vi != v.end(); ++vi) ++m[*vi];</p><p>for (auto mi = m.begin(); mi != m.end(); ++mi) </p><p> cout << mi->first << ": " << mi->second << endl;</p><p><br /></p><p>Y listo!</p>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-88733915726152197602024-03-09T14:11:00.001-03:002024-03-09T14:11:02.939-03:00 Asignaciones en Gleam<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHslfb5FlL9BdcWKGqObyMMvhMoTVo8-dyO34fC9sLLifsNORdmzTbLIaa8rKly2MIAOdVEN1T2nKNd2zgBUh2MUhhuZxdcoGat7q9RpkiLF69PDRnAMcZpanhThvr8Xf-86k8yC5G-PuYR7cV13mVo7agSeb_7f2c6MJrbw0nZsiJBn_yhwZVPvToA28/s225/Gleam.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="225" data-original-width="225" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHslfb5FlL9BdcWKGqObyMMvhMoTVo8-dyO34fC9sLLifsNORdmzTbLIaa8rKly2MIAOdVEN1T2nKNd2zgBUh2MUhhuZxdcoGat7q9RpkiLF69PDRnAMcZpanhThvr8Xf-86k8yC5G-PuYR7cV13mVo7agSeb_7f2c6MJrbw0nZsiJBn_yhwZVPvToA28/s1600/Gleam.png" width="225" /></a></div><br />import gleam/io<p></p><p><br /></p><p>pub fn main() {</p><p> let x = "Original"</p><p> io.debug(x)</p><p><br /></p><p> // Assign `y` to the value of `x`</p><p> let y = x</p><p> io.debug(y)</p><p><br /></p><p> // Assign `x` to a new value</p><p> let x = "New"</p><p> io.debug(x)</p><p><br /></p><p> // The `y` still refers to the original value</p><p> io.debug(y)</p><p>}</p><p><br /></p><p>Se puede asignar un valor a una variable usando let.</p><p>Los nombres de las variables se pueden reutilizar mediante enlaces let posteriores, pero los valores a los que hacen referencia son inmutables, por lo que los valores en sí no se modifican ni mutan de ninguna manera.</p>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-5152988401121519942024-03-08T06:45:00.000-03:002024-03-08T06:45:19.734-03:00Un ejemplo utilizando STL de C++<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj64t9krjd88PA6sRGYRqOCoWxQNIZKSU5MQQILvlFNhmSgmiXm_hAFAWBxBdLQNRXoqHduBdBhEMJg5VT1ZdI2u-1Rxoqe7kqD6Vbsmf1ASJzoR5KXELUApON44XugTeRsez2R2P4UIwKoiXTD-isYRPGjqonp2txTEJUlsrh1658LTO2zve4KwElMLKY/s1349/cpp.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1349" data-original-width="1200" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj64t9krjd88PA6sRGYRqOCoWxQNIZKSU5MQQILvlFNhmSgmiXm_hAFAWBxBdLQNRXoqHduBdBhEMJg5VT1ZdI2u-1Rxoqe7kqD6Vbsmf1ASJzoR5KXELUApON44XugTeRsez2R2P4UIwKoiXTD-isYRPGjqonp2txTEJUlsrh1658LTO2zve4KwElMLKY/s320/cpp.png" width="285" /></a></div><br />Voy hacer unos post con ejemplos de utilización de la Stl de C++. Vamos con el primero: <p></p><p>Leamos una cantidad arbitraria de valores enteros (n>=1) del archivo “numbers.txt” y mostramos:</p><p></p><ul style="text-align: left;"><li>Mínimo, máximo</li><li>Media</li><li>Promedio</li><li>Media geométrica ((y1 * y2 * … yn)^(1/n))</li></ul><p></p><p style="text-align: left;">Con Stl sería así: </p><p>vector<int> v;</p><p>copy(istream_iterator<int>(ifstream("numbers.txt")), istream_iterator<int>(), back_inserter(v));</p><p>sort(v.begin(), v.end());</p><p>cout << "min/max: " << v.front() << " " << v.back() << endl;</p><p>cout << "median : " << *(v.begin() + (v.size()/2)) << endl;</p><p>cout << "average: " << accumulate(v.begin(), v.end(), 0.0) / v.size() << endl;</p><p>cout << "geomean: " << pow(accumulate(v.begin(),v.end(),1.0,multiplies<double>()), 1.0/v.size()) </p><p><< endl;</p><p>Y listo!</p>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-13770567275371129472024-03-06T22:34:00.000-03:002024-03-06T22:34:56.343-03:00Strings en Gleam<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfquIQGEGBuUTEMJFs11mZyU0eulqagu-gahDCy4K4O77od7OuvXYUsaupQ3zAVVXyqmM1wjyNf-LCEsJZJu7YyOspDTmfCRaXFWwCO9MpU202deZinMm7ypCL3cRuLD1cNNfKSBrQu6MYzmlKWJqrvf8WxYTIUlOWfaI0ZLp0OvlOdYxpP5XvRS6Snno/s225/Gleam.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="225" data-original-width="225" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfquIQGEGBuUTEMJFs11mZyU0eulqagu-gahDCy4K4O77od7OuvXYUsaupQ3zAVVXyqmM1wjyNf-LCEsJZJu7YyOspDTmfCRaXFWwCO9MpU202deZinMm7ypCL3cRuLD1cNNfKSBrQu6MYzmlKWJqrvf8WxYTIUlOWfaI0ZLp0OvlOdYxpP5XvRS6Snno/s1600/Gleam.png" width="225" /></a></div><br /><p><br /></p><p>import gleam/io</p><p>import gleam/string</p><p><br /></p><p>pub fn main() {</p><p> // String literals</p><p> io.debug("👩💻 こんにちは Gleam 🏳️🌈")</p><p> io.debug(</p><p> "multi</p><p> line</p><p> string",</p><p> )</p><p> io.debug("\u{1F600}")</p><p><br /></p><p> // Double quote can be escaped</p><p> io.println("\"X\" marks the spot")</p><p><br /></p><p> // String concatenation</p><p> io.debug("One " <> "Two")</p><p><br /></p><p> // String functions</p><p> io.debug(string.reverse("1 2 3 4 5"))</p><p> io.debug(string.append("abc", "def"))</p><p>}</p><div><div><br /></div><div>En Gleam, las cadenas se escriben como texto entre comillas dobles, pueden abarcar varias líneas y contener caracteres Unicode.</div><div><br /></div><div>El operador <> se puede utilizar para concatenar cadenas.</div><div><br /></div><div>Se admiten varias secuencias de escape:</div><div><br /></div><div>\" - comillas dobles</div><div>\\ - barra invertida</div><div>\f - avance de formulario</div><div>\n - nueva línea</div><div>\r - retorno de carro</div><div>\t - pestaña</div><div>\u{xxxxxx} - punto de código Unicode</div><div><br /></div><div>El módulo de biblioteca estándar <a href="https://hexdocs.pm/gleam_stdlib/gleam/string.html" target="_blank">gleam/string</a> contiene funciones para trabajar con cadenas.</div></div>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-60077683343673691252024-03-06T22:25:00.000-03:002024-03-06T22:25:08.765-03:00Primera API con Go-zero<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDXPLB9DwdAca3KSfij3MVw6pxE_gAUKqLqTseSfOYsfo07qj93_P2iQ4tPaRfDKN0WUIOv9qPhsGzpPenVSyGrVA8VfkiyvrA8zS2mMJ7wL-z36U8SaWk34skCBVgFcD-4eka2ur3HsSm4mW24F2Q41iTGj8jS18uxcz491fR4cDMlUrwTZ5OQXM0uYo/s512/go-zero.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="512" data-original-width="512" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDXPLB9DwdAca3KSfij3MVw6pxE_gAUKqLqTseSfOYsfo07qj93_P2iQ4tPaRfDKN0WUIOv9qPhsGzpPenVSyGrVA8VfkiyvrA8zS2mMJ7wL-z36U8SaWk34skCBVgFcD-4eka2ur3HsSm4mW24F2Q41iTGj8jS18uxcz491fR4cDMlUrwTZ5OQXM0uYo/s320/go-zero.png" width="320" /></a></div><br />Después de completar<a href="https://emanuelpeg.blogspot.com/2024/02/instalando-go-zero.html" target="_blank"> la instalación</a> de goctl, podemos crear un servicio HTTP mínimo para obtener una descripción general del servicio API go-zero de goctl.<p></p><p><br /></p><p># Create workspaces and enter the directory</p><p>$ mkdir -p ~/workspace/api && cd ~/workspace/api</p><p># Execute instructions generated demo service</p><p>$ goctl api new demo</p><p>Done.</p><p><br /></p><p>Después de ejecutar la instrucción, se generará un directorio de demostración en el directorio actual que contiene un servicio HTTP minimizado, verificaremos la estructura del directorio del servicio.</p><p><br /></p><p>$ cd ~/workspace/api/demo</p><p>$ ls</p><p>demo.api demo.go etc go.mod internal</p><p>$ tree</p><p>.</p><p>├── demo.api</p><p>├── demo.go</p><p>├── etc</p><p>│ └── demo-api.yaml</p><p>├── go.mod</p><p>└── internal</p><p> ├── config</p><p> │ └── config.go</p><p> ├── handler</p><p> │ ├── demohandler.go</p><p> │ └── routes.go</p><p> ├── logic</p><p> │ └── demologic.go</p><p> ├── svc</p><p> │ └── servicecontext.go</p><p> └── types</p><p> └── types.go</p><p><br /></p><p>Después de completar la generación del código anterior, podemos encontrar los archivos ~/workspace/api/demo/internal/logic/demologic.go, y podemos completar el códigos entre las líneas 27 y 28:</p><p>resp = new(types.Response)</p><p>resp.Message = req.Name</p><p><br /></p><p>Después de escribir el código anterior, podemos iniciar el servicio con las siguientes instrucciones:</p><p><br /></p><p># Enter service directory</p><p>$ cd ~/workspace/api/demo</p><p># to organize dependencies</p><p>$ go mod tidy</p><p># Run go program</p><p>$ go run demo.go</p><p><br /></p><p>Cuando vea el siguiente resultado "Starting server at 0.0.0.0.0:888.." indica que el servicio se ha iniciado correctamente, entonces visitamos el servicio HTTP.</p><p><br /></p><p>$ curl --request GET 'http://127.0.0.0.1:8888/from/me'</p><p><br /></p><p>Cuando vea el resultado en la terminal {"message":"me"} en nombre de su servicio se inició con éxito.</p><p><br /></p><p>Y listo!!</p><p>Dejo link: <a href="https://go-zero.dev/en/docs/tasks/cli/api-demo">https://go-zero.dev/en/docs/tasks/cli/api-demo</a></p><p><br /></p>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-69820512167441719952024-03-06T22:06:00.000-03:002024-03-06T22:06:47.324-03:00Bools en Gleam<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJqSMpfUYp6buySy18iqLIFRoiRBK7Pt72K51NhOwe9pG1P8-zm1_yypVhymS39fc4W6jDo8CFkCKBep_OJhZDMki6frzOjuZVjyhariFy4g93ff96GN0U-d_gf5lO5efu1A5H47ZPdbCYK9ucilxJkWtFUTtq95ReVcyhAQReuCKYcvQ_7lUwlk5_uY0/s225/Gleam.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="225" data-original-width="225" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJqSMpfUYp6buySy18iqLIFRoiRBK7Pt72K51NhOwe9pG1P8-zm1_yypVhymS39fc4W6jDo8CFkCKBep_OJhZDMki6frzOjuZVjyhariFy4g93ff96GN0U-d_gf5lO5efu1A5H47ZPdbCYK9ucilxJkWtFUTtq95ReVcyhAQReuCKYcvQ_7lUwlk5_uY0/s1600/Gleam.png" width="225" /></a></div><br /><p><br /></p><p>import gleam/io</p><p>import gleam/bool</p><p><br /></p><p>pub fn main() {</p><p> // Bool operators</p><p> io.debug(True && False)</p><p> io.debug(True && True)</p><p> io.debug(False || False)</p><p> io.debug(False || True)</p><p><br /></p><p> // Bool functions</p><p> io.debug(bool.to_string(True))</p><p> io.debug(bool.to_int(False))</p><p>}</p><p><br /></p><div><div>Un Bool es Verdadero o Falso.</div><div><br /></div><div>El ||, &&, y ! Los operadores se pueden utilizar para manipular bools.</div><div><br /></div><div>El || y los operadores && están en cortocircuito, lo que significa que si el lado izquierdo del operador es Verdadero para || o False para && entonces no se evaluará el lado derecho del operador.</div><div><br /></div><div>El módulo de biblioteca estándar <a href="https://hexdocs.pm/gleam_stdlib/gleam/bool.html" target="_blank">gleam/bool</a> contiene funciones para trabajar con bools.</div></div><div><br /></div>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-6312800266029133762024-03-06T21:49:00.003-03:002024-03-06T21:49:39.371-03:00 Ponte al día con la IA generativa<p> Me llego este mail de la gente de google y quería compartirlo: </p><p><br /></p><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none; width: 700px;"><td align="center" style="outline: none; word-break: normal;"><div style="margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; margin-left: 0px; margin-right: 0px; outline: none; width: 500px;"><tbody style="outline: none;"><tr style="outline: none; width: 200px;"><td class="yiv2031201520block-grid yiv2031201520padding-24px-24px-24px-50px" style="font-size: 0px; outline: none; padding: 2px; text-align: center; vertical-align: top; width: 20; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; line-height: 0; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 526px;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; vertical-align: middle; width: 526px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: middle; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520img-container" style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div class="yiv2031201520max-width-180px" style="margin: 0px auto 0px 0px; max-width: 140px; outline: none;"><div class="yiv2031201520mktoImg" id="yiv2031201520kimage-tg2t80n2g" style="outline: none;"><img alt="Google Cloud logo" height="auto" src="https://ecp.yusercontent.com/mail?url=https%3A%2F%2Fgstatic.com%2Fgrowthlab%2Fapi%2FpvanXOFXvQzwEt7WwHhCsjNVFmGYBI9yZ2y7gpwV.png&t=1709771243&ymreqid=7a46a144-bd8e-e278-1ce7-bf08fc019200&sig=wAtM82.UZss4jZqNhbtmRA--~D" style="border: none; display: block; font-size: 13px; height: auto; line-height: 13px; outline: none; text-indent: -9999px; width: 180px;" width="180" /></div></div></td></tr></tbody></table></div></div></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background: rgb(255, 255, 255); margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid yiv2031201520padding-40px-50px-4px-50px" style="font-size: 0px; outline: none; padding: 10px 25px 4px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520text-container" style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div class="yiv2031201520mktEditable" id="yiv2031201520ktext-ocqyfyry6" style="color: #202124; font-family: "Google Sans Display", "Google Sans", "Noto Sans JP", Arial, sans-serif; font-size: 24px; font-weight: 700; line-height: 1.3; outline: none;"><div class="yiv2031201520links-1A73E8-underline" style="outline: none;"><div class="yiv2031201520mso-font-size-32px yiv2031201520font-size-32px yiv2031201520line-height-1-20" style="line-height: 1.3; outline: none;"><p style="margin: 0px; outline: none;">Ponte al día con la <span style="color: #1a73e8; outline: none;">IA generativa</span></p></div></div></div></td></tr></tbody></table></div></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background: rgb(255, 255, 255); margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid yiv2031201520padding-14px-50px-16px-50px" style="font-size: 0px; outline: none; padding: 14px 25px 16px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520text-container" style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div class="yiv2031201520mktEditable" id="yiv2031201520ktext-tviamws7a" style="color: #5f6368; font-family: "Google Sans", "Noto Sans JP", Arial, sans-serif; font-size: 16px; letter-spacing: 0px; line-height: 1.6; outline: none;"><div class="yiv2031201520links-1A73E8-underline" style="outline: none;"><div style="letter-spacing: 0px; line-height: 1.6; outline: none;"><p style="margin: 0px; outline: none;">¿Quieres saber cómo la IA generativa afectará a tu empresa? Estos recursos te ayudarán a mantenerte al día respecto de este tema tan cambiante.</p></div></div></div></td></tr></tbody></table></div></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background: rgb(255, 255, 255); margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid yiv2031201520padding-16px-50px-18px-50px" style="font-size: 0px; outline: none; padding: 16px 25px 18px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520img-container" style="font-size: 0px; outline: none; padding: 0px; text-align: center; word-break: normal;"><div class="yiv2031201520img-full-width" style="margin: 0px auto; max-width: 500px; outline: none;"><div class="yiv2031201520mktoImg" id="yiv2031201520kimage-dot25b6ev" style="outline: none;"><img height="auto" src="https://ecp.yusercontent.com/mail?url=https%3A%2F%2Flp.cloudplatformonline.com%2Frs%2F808-GJW-314%2Fimages%2FGenAI_Email_Header_Light_1820x1362.png%3Fversion%3D0&t=1709771243&ymreqid=7a46a144-bd8e-e278-1ce7-bf08fc019200&sig=9HWJDk2PcN2WqFmjlE.0iw--~D" style="border: 0px; height: auto; line-height: 0px; outline: none; text-indent: -9999px;" width="500" /></div></div></td></tr></tbody></table></div></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background: rgb(255, 255, 255); margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid yiv2031201520padding-16px-50px-4px-50px" style="font-size: 0px; outline: none; padding: 16px 25px 4px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520text-container" style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div class="yiv2031201520mktEditable" id="yiv2031201520ktext-38wdz06wc" style="color: #5f6368; font-family: "Google Sans Text", "Google Sans", "Noto Sans JP", Arial, sans-serif; font-size: 14px; font-weight: 700; line-height: 1.7; outline: none;"><div class="yiv2031201520links-1A73E8-underline" style="outline: none;"><div style="line-height: 1.7; outline: none;"><p style="margin: 0px; outline: none;"><span style="font-weight: 400; outline: none;"><strong style="outline: none;">Hola Emanuel,</strong></span></p></div></div></div></td></tr></tbody></table></div></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background: rgb(255, 255, 255); margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid yiv2031201520padding-8px-50px-8px-50px" style="font-size: 0px; outline: none; padding: 8px 25px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520text-container" style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div class="yiv2031201520mktEditable" id="yiv2031201520ktext-b2w6ags2r" style="color: #5f6368; font-family: "Google Sans Text", "Google Sans", "Noto Sans JP", Arial, sans-serif; font-size: 14px; line-height: 1.5; outline: none;"><div class="yiv2031201520links-1A73E8-underline" style="outline: none;"><div style="line-height: 1.5; outline: none;"><p style="margin: 0px; outline: none;">El revuelo que causa la IA generativa no es algo que pueda ignorarse. De hecho, el 82% de los ejecutivos prevén que esta tecnología transformará considerablemente su industria.1 Con tanto alboroto, seguir el paso puede ser una tarea difícil.</p></div></div></div></td></tr></tbody></table></div></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background: rgb(255, 255, 255); margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid yiv2031201520padding-8px-50px-8px-50px" style="font-size: 0px; outline: none; padding: 8px 25px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520text-container" style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div class="yiv2031201520mktEditable" id="yiv2031201520ktext-z07bxtyjp" style="color: #5f6368; font-family: "Google Sans Text", "Google Sans", "Noto Sans JP", Arial, sans-serif; font-size: 14px; line-height: 1.5; outline: none;"><div class="yiv2031201520links-1A73E8-underline" style="outline: none;"><div style="line-height: 1.5; outline: none;"><p style="margin: 0px; outline: none;">Este es el primer correo electrónico que recibirás de una serie que te brindará recursos útiles relacionados con la IA generativa. En las próximas semanas, exploraremos todas las tendencias clave y los problemas que los líderes empresariales como tú deben conocer, lo que te permitirá materializar su potencial en tu negocio.</p></div></div></div></td></tr></tbody></table></div></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background: rgb(255, 255, 255); margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid yiv2031201520padding-8px-50px-8px-50px" style="font-size: 0px; outline: none; padding: 8px 25px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520text-container" style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div class="yiv2031201520mktEditable" id="yiv2031201520ktext-aevku85ps" style="color: #5f6368; font-family: "Google Sans Text", "Google Sans", "Noto Sans JP", Arial, sans-serif; font-size: 14px; line-height: 1.5; outline: none;"><div class="yiv2031201520links-1A73E8-underline" style="outline: none;"><div style="line-height: 1.5; outline: none;"><p style="margin: 0px; outline: none;"><strong style="outline: none;">Descubre la jerga de la IA generativa </strong></p></div></div></div></td></tr></tbody></table></div></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background: rgb(255, 255, 255); margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid yiv2031201520padding-8px-50px-8px-50px" style="font-size: 0px; outline: none; padding: 8px 25px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520text-container" style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div class="yiv2031201520mktEditable" id="yiv2031201520ktext-csbks6ylo" style="color: #5f6368; font-family: "Google Sans Text", "Google Sans", "Noto Sans JP", Arial, sans-serif; font-size: 14px; line-height: 1.5; outline: none;"><div class="yiv2031201520links-1A73E8-underline" style="outline: none;"><div style="line-height: 1.5; outline: none;"><p style="margin: 0px; outline: none;">Para adoptar la tecnología revolucionaria de la IA generativa, es necesario conocer todos los nuevos términos y frases que se relacionan con ella. Por ejemplo, el ajuste de instrucciones o "prompt tuning" en inglés, las incorporaciones, los modelos de base y mucho más.</p></div></div></div></td></tr></tbody></table></div></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background: rgb(255, 255, 255); margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid yiv2031201520padding-8px-50px-8px-50px" style="font-size: 0px; outline: none; padding: 8px 25px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520text-container" style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div class="yiv2031201520mktEditable" id="yiv2031201520ktext-21bjd5ol8" style="color: #5f6368; font-family: "Google Sans Text", "Google Sans", "Noto Sans JP", Arial, sans-serif; font-size: 14px; line-height: 1.5; outline: none;"><div class="yiv2031201520links-1A73E8-underline" style="outline: none;"><div style="line-height: 1.5; outline: none;"><p style="margin: 0px; outline: none;">Si eres un ejecutivo atareado, comprender la terminología de una tecnología nueva puede parecerte difícil de lograr. Este artículo útil explica el lenguaje que debes conocer para explorar cómo la IA generativa podría transformar tu negocio.</p></div></div></div></td></tr></tbody></table></div></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background: rgb(255, 255, 255); margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid yiv2031201520padding-8px-50px-8px-50px" style="font-size: 0px; outline: none; padding: 8px 25px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520text-container" style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div class="yiv2031201520mktEditable" id="yiv2031201520ktext-h39yvz3sr" style="color: #5f6368; font-family: "Google Sans Text", "Google Sans", "Noto Sans JP", Arial, sans-serif; font-size: 14px; line-height: 1.5; outline: none;"><div class="yiv2031201520links-1A73E8-underline" style="outline: none;"><div style="line-height: 1.5; outline: none;"><p style="margin: 0px; outline: none;"><a href="https://go.cloudplatformonline.com/ODA4LUdKVy0zMTQAAAGRtCb4A1sAwtxp0vyTtf44EOVTwiYSbXaaP3SQLE1XQ_RDFnCfj3vbC-SCRh5_Y3-OWIMKNdg=" rel="nofollow noopener noreferrer" style="color: #1a73e8; outline: none;" target="_blank">Lee el manual de la IA generativa</a></p></div></div></div></td></tr></tbody></table></div></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background: rgb(255, 255, 255); margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid yiv2031201520padding-8px-50px-8px-50px" style="font-size: 0px; outline: none; padding: 8px 25px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520text-container" style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div class="yiv2031201520mktEditable" id="yiv2031201520ktext-ugh4q6s4c" style="color: #5f6368; font-family: "Google Sans Text", "Google Sans", "Noto Sans JP", Arial, sans-serif; font-size: 14px; line-height: 1.5; outline: none;"><div class="yiv2031201520links-1A73E8-underline" style="outline: none;"><div style="line-height: 1.5; outline: none;"><p style="margin: 0px; outline: none;"><strong style="outline: none;">Explora las oportunidades en las diferentes industrias</strong></p></div></div></div></td></tr></tbody></table></div></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background: rgb(255, 255, 255); margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid yiv2031201520padding-8px-50px-8px-50px" style="font-size: 0px; outline: none; padding: 8px 25px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520text-container" style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div class="yiv2031201520mktEditable" id="yiv2031201520ktext-viucqklaa" style="color: #5f6368; font-family: "Google Sans Text", "Google Sans", "Noto Sans JP", Arial, sans-serif; font-size: 14px; line-height: 1.5; outline: none;"><div class="yiv2031201520links-1A73E8-underline" style="outline: none;"><div style="line-height: 1.5; outline: none;"><p style="margin: 0px; outline: none;">A través de sus diversos usos, como posibilitar interacciones en línea más conversacionales o un acceso intuitivo a datos complejos, la IA generativa está reformulando los procesos de negocio. </p></div></div></div></td></tr></tbody></table></div></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background: rgb(255, 255, 255); margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid yiv2031201520padding-8px-50px-8px-50px" style="font-size: 0px; outline: none; padding: 8px 25px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520text-container" style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div class="yiv2031201520mktEditable" id="yiv2031201520ktext-rjyxo2t87" style="color: #5f6368; font-family: "Google Sans Text", "Google Sans", "Noto Sans JP", Arial, sans-serif; font-size: 14px; line-height: 1.5; outline: none;"><div class="yiv2031201520links-1A73E8-underline" style="outline: none;"><div style="line-height: 1.5; outline: none;"><p style="margin: 0px; outline: none;">Con un potencial tan amplio, a los líderes empresariales les interesa conocer los usos y las oportunidades específicas para su industria o su organización. En este artículo, se examinan las posibilidades en varias industrias clave.</p></div></div></div></td></tr></tbody></table></div></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background: rgb(255, 255, 255); margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid yiv2031201520padding-8px-50px-8px-50px" style="font-size: 0px; outline: none; padding: 8px 25px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520text-container" style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div class="yiv2031201520mktEditable" id="yiv2031201520ktext-41i115pie" style="color: #5f6368; font-family: "Google Sans Text", "Google Sans", "Noto Sans JP", Arial, sans-serif; font-size: 14px; line-height: 1.5; outline: none;"><div class="yiv2031201520links-1A73E8-underline" style="outline: none;"><div style="line-height: 1.5; outline: none;"><a href="https://go.cloudplatformonline.com/ODA4LUdKVy0zMTQAAAGRtCb4BG2UvQuhKzUj9hgB1Nol6lcaT8CWRyuwatt4m8fetyM7NcsYjliQzMBOCFAwY51cRgI=" rel="nofollow noopener noreferrer" style="color: #1a73e8; outline: none;" target="_blank"><p style="margin: 0px; outline: none;">Lee el artículo</p></a></div></div></div></td></tr></tbody></table></div></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background: rgb(255, 255, 255); margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid yiv2031201520padding-8px-50px-8px-50px" style="font-size: 0px; outline: none; padding: 8px 25px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520text-container" style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div class="yiv2031201520mktEditable" id="yiv2031201520ktext-4l49ba2df" style="color: #5f6368; font-family: "Google Sans Text", "Google Sans", "Noto Sans JP", Arial, sans-serif; font-size: 14px; line-height: 1.5; outline: none;"><div class="yiv2031201520links-1A73E8-underline" style="outline: none;"><div style="line-height: 1.5; outline: none;"><p style="margin: 0px; outline: none;"><strong style="outline: none;">Domina los conceptos más importantes de la IA generativa</strong></p></div></div></div></td></tr></tbody></table></div></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background: rgb(255, 255, 255); margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid yiv2031201520padding-8px-50px-8px-50px" style="font-size: 0px; outline: none; padding: 8px 25px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520text-container" style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div class="yiv2031201520mktEditable" id="yiv2031201520ktext-e9vkofxx1" style="color: #5f6368; font-family: "Google Sans Text", "Google Sans", "Noto Sans JP", Arial, sans-serif; font-size: 14px; line-height: 1.5; outline: none;"><div class="yiv2031201520links-1A73E8-underline" style="outline: none;"><div style="line-height: 1.5; outline: none;"><p style="margin: 0px; outline: none;">Si bien la IA generativa es un tema increíblemente amplio, surgieron algunos conceptos clave en los últimos meses. Para finalizar, te recomendamos que leas este artículo, que resume los conceptos clave más relevantes para líderes empresariales como tú. </p></div></div></div></td></tr></tbody></table></div></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background: rgb(255, 255, 255); margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid yiv2031201520padding-8px-50px-8px-50px" style="font-size: 0px; outline: none; padding: 8px 25px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520text-container" style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div class="yiv2031201520mktEditable" id="yiv2031201520ktext-5vn2g4heo" style="color: #5f6368; font-family: "Google Sans Text", "Google Sans", "Noto Sans JP", Arial, sans-serif; font-size: 14px; line-height: 1.5; outline: none;"><div class="yiv2031201520links-1A73E8-underline" style="outline: none;"><div style="line-height: 1.5; outline: none;"><a href="https://go.cloudplatformonline.com/ODA4LUdKVy0zMTQAAAGRtCb4BH9BATySD9c3qNYa_SLdXrn4KqpdJUgF4sPJOml1EgsrhuhPpByWqZQwFzgLrOQZEiM=" rel="nofollow noopener noreferrer" style="color: #1a73e8; outline: none;" target="_blank"><p style="margin: 0px; outline: none;">Obtén más información sobre los conceptos principales de la IA generativa</p></a></div></div></div></td></tr></tbody></table></div></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background: rgb(255, 255, 255); margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid yiv2031201520padding-8px-50px-30px-50px" style="font-size: 0px; outline: none; padding: 8px 25px 30px; text-align: center; vertical-align: top; word-break: normal;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td style="direction: rtl; font-size: 0px; line-height: 0; outline: none; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520text-container" style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div class="yiv2031201520mktEditable" id="yiv2031201520ktext-87ay7q3ra" style="color: #5f6368; font-family: "Google Sans", "Noto Sans JP", Arial, sans-serif; font-size: 14px; line-height: 1.7; outline: none;"><div class="yiv2031201520links-1A73E8-underline" style="outline: none;"><div style="line-height: 1.7; outline: none;"><p style="margin: 0px; outline: none;">Nos vemos en la nube,</p></div></div></div></td></tr><tr style="outline: none;"><td style="outline: none; word-break: normal;"><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="border-spacing: 0px; outline: none; width: 500px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="font-size: 0px; outline: none; padding: 0px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520text-container" style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div class="yiv2031201520mktEditable" id="yiv2031201520ktext-ztzjx4xux" style="color: #5f6368; font-family: "Google Sans", "Noto Sans JP", Arial, sans-serif; font-size: 14px; line-height: 1.7; outline: none;"><div class="yiv2031201520links-1A73E8-underline" style="outline: none;"><div style="line-height: 1.7; outline: none;"><p style="margin: 0px; outline: none;"><strong style="outline: none;">El equipo de Google Cloud</strong></p></div></div></div></td></tr></tbody></table></div></td></tr></tbody></table></td></tr></tbody></table></div></td></tr></tbody></table></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background: rgb(255, 255, 255); margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid yiv2031201520padding-8px-50px-8px-50px" style="font-size: 0px; outline: none; padding: 8px 25px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520text-container" style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div class="yiv2031201520mktEditable" id="yiv2031201520ktext-boyd65dp0" style="color: #5f6368; font-family: "Google Sans Text", "Google Sans", "Noto Sans JP", Arial, sans-serif; font-size: 12px; line-height: 1.7; outline: none;"><div class="yiv2031201520links-1A73E8-underline" style="outline: none;"><div style="line-height: 1.7; outline: none;"><p style="margin: 0px; outline: none;">1. Google<span class="yiv2031201520mce-nbsp-wrap" style="outline: none;"> </span>Cloud Gen IA Benchmarking Study, julio de 2023</p></div></div></div></td></tr><tr style="outline: none;"><td style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><div style="line-height: 20px; min-height: 20px; outline: none;"> </div></td></tr></tbody></table></div></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background: rgb(255, 255, 255); margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid" style="font-size: 0px; outline: none; padding: 0px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 600px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520img-container" style="font-size: 0px; outline: none; padding: 0px; text-align: center; word-break: normal;"><div style="margin: 0px auto; outline: none;"><div class="yiv2031201520mktoImg" id="yiv2031201520kimage-33x3cvyv8" style="outline: none;"><img height="auto" src="https://ecp.yusercontent.com/mail?url=https%3A%2F%2Fgstatic.com%2Fgrowthlab%2Fapi%2FHLtoQ5eEyrqFOCa8RTHSbwOKmZPkDh6h8tEpWsxf.png&t=1709771243&ymreqid=7a46a144-bd8e-e278-1ce7-bf08fc019200&sig=jqq0Li.xBFEtiTNhUNZ4Mw--~D" style="border: none; display: block; font-size: 13px; height: auto; line-height: 13px; outline: none; text-indent: -9999px; width: 600px;" width="600" /></div></div></td></tr></tbody></table></div></td></tr></tbody></table></div></td></tr></tbody></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="yiv2031201520section" role="presentation" style="background-color: #f8f9fa; border-spacing: 0px; color: #1d2228; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; outline: none; width: 700px;"><tbody style="outline: none;"><tr style="outline: none;"><td align="center" style="outline: none; word-break: normal;"><div style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; margin: 0px auto; max-width: 600px; outline: none;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; outline: none; width: 600px;"><tbody style="outline: none;"><tr style="outline: none;"><td class="yiv2031201520block-grid yiv2031201520padding-40px-50px-0px-50px" style="font-size: 0px; outline: none; padding: 40px 25px 0px; text-align: center; vertical-align: top; word-break: normal;"><div class="yiv2031201520mj-column-per-100 yiv2031201520mj-outlook-group-fix" style="direction: ltr; display: inline-block; max-width: 100%; outline: none; text-align: left; vertical-align: top; width: 500px;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius: 0px; border-spacing: 0px; outline: none; vertical-align: top; width: 100%;"><tbody style="outline: none;"><tr style="outline: none;"><td style="font-size: 0px; outline: none; padding: 0px; word-break: normal;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-spacing: 0px; font-family: "Google Sans", "Noto Sans JP", Arial, sans-serif; font-size: 13px; line-height: 1; outline: none; width: 500px;"><tbody style="outline: none;"><tr style="outline: none;"><td style="outline: none; vertical-align: top; word-break: normal;"></td></tr></tbody></table></td></tr><tr style="outline: none;"><td class="yiv2031201520img-container" style="font-size: 0px; outline: none; padding: 0px 0px 16px; word-break: normal;"><div style="margin: 0px auto 0px 0px; max-width: 140px; outline: none;"><div class="yiv2031201520mktoImg" id="yiv2031201520kimage-de07exqfi" style="outline: none;"><img alt="Google Cloud logo" height="auto" src="https://ecp.yusercontent.com/mail?url=https%3A%2F%2Fgstatic.com%2Fgrowthlab%2Fapi%2F2A9vlxcGS37IiXj1x6voJqDiNsMiZu9Y05S8PNZv.png&t=1709771243&ymreqid=7a46a144-bd8e-e278-1ce7-bf08fc019200&sig=7j.EMfosmq3GklRjPrpFnQ--~D" style="border: none; display: block; font-size: 13px; height: auto; line-height: 13px; outline: none; text-indent: -9999px; width: 140px;" width="140" /></div></div></td></tr></tbody></table></div></td></tr></tbody></table></div></td></tr></tbody></table>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-8457213002233229132024-03-05T23:04:00.000-03:002024-03-05T23:04:46.530-03:00Igualdad en Gleam<p> </p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJqSMpfUYp6buySy18iqLIFRoiRBK7Pt72K51NhOwe9pG1P8-zm1_yypVhymS39fc4W6jDo8CFkCKBep_OJhZDMki6frzOjuZVjyhariFy4g93ff96GN0U-d_gf5lO5efu1A5H47ZPdbCYK9ucilxJkWtFUTtq95ReVcyhAQReuCKYcvQ_7lUwlk5_uY0/s225/Gleam.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="225" data-original-width="225" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJqSMpfUYp6buySy18iqLIFRoiRBK7Pt72K51NhOwe9pG1P8-zm1_yypVhymS39fc4W6jDo8CFkCKBep_OJhZDMki6frzOjuZVjyhariFy4g93ff96GN0U-d_gf5lO5efu1A5H47ZPdbCYK9ucilxJkWtFUTtq95ReVcyhAQReuCKYcvQ_7lUwlk5_uY0/s1600/Gleam.png" width="225" /></a></div><br /><br /><p></p><p>import gleam/io</p><p><br /></p><p>pub fn main() {</p><p> io.debug(100 == 100)</p><p> io.debug(1.5 != 0.1)</p><p>}</p><div><br /></div><p>Gleam tiene los operadores == y != para verificar la igualdad.</p><p>Los operadores se pueden utilizar con valores de cualquier tipo, pero ambos lados del operador deben ser del mismo tipo.</p><p>La igualdad se verifica estructuralmente, lo que significa que dos valores son iguales si tienen la misma estructura y no si están en la misma ubicación de memoria.</p>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-80169599600459867862024-03-04T22:35:00.000-03:002024-03-04T22:35:16.803-03:00Formatos de números en Gleam<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJqSMpfUYp6buySy18iqLIFRoiRBK7Pt72K51NhOwe9pG1P8-zm1_yypVhymS39fc4W6jDo8CFkCKBep_OJhZDMki6frzOjuZVjyhariFy4g93ff96GN0U-d_gf5lO5efu1A5H47ZPdbCYK9ucilxJkWtFUTtq95ReVcyhAQReuCKYcvQ_7lUwlk5_uY0/s225/Gleam.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="225" data-original-width="225" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJqSMpfUYp6buySy18iqLIFRoiRBK7Pt72K51NhOwe9pG1P8-zm1_yypVhymS39fc4W6jDo8CFkCKBep_OJhZDMki6frzOjuZVjyhariFy4g93ff96GN0U-d_gf5lO5efu1A5H47ZPdbCYK9ucilxJkWtFUTtq95ReVcyhAQReuCKYcvQ_7lUwlk5_uY0/s1600/Gleam.png" width="225" /></a></div><br />import gleam/io<p></p><p><br /></p><p>pub fn main() {</p><p> // Underscores</p><p> io.debug(1_000_000)</p><p> io.debug(10_000.01)</p><p><br /></p><p> // Binary, octal, and hex Int literals</p><p> io.debug(0b00001111)</p><p> io.debug(0o17)</p><p> io.debug(0xF)</p><p><br /></p><p> // Scientific notation Float literals</p><p> io.debug(7.0e7)</p><p> io.debug(3.0e-4)</p><p>}</p><p>Se pueden agregar guiones bajos a los números para mayor claridad. Por ejemplo, 1000000 puede ser complicado de leer rápidamente, mientras que 1_000_000 puede ser más fácil.</p><p>Los enteros se pueden escribir en formatos binario, octal o hexadecimal utilizando los prefijos 0b, 0o y 0x respectivamente.</p><p>Los flotantes se pueden escribir en notación científica.</p>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-66449615751039303742024-03-04T01:54:00.000-03:002024-03-04T01:54:28.411-03:00El tipo Float de Gleam<p> </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfquIQGEGBuUTEMJFs11mZyU0eulqagu-gahDCy4K4O77od7OuvXYUsaupQ3zAVVXyqmM1wjyNf-LCEsJZJu7YyOspDTmfCRaXFWwCO9MpU202deZinMm7ypCL3cRuLD1cNNfKSBrQu6MYzmlKWJqrvf8WxYTIUlOWfaI0ZLp0OvlOdYxpP5XvRS6Snno/s225/Gleam.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="225" data-original-width="225" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfquIQGEGBuUTEMJFs11mZyU0eulqagu-gahDCy4K4O77od7OuvXYUsaupQ3zAVVXyqmM1wjyNf-LCEsJZJu7YyOspDTmfCRaXFWwCO9MpU202deZinMm7ypCL3cRuLD1cNNfKSBrQu6MYzmlKWJqrvf8WxYTIUlOWfaI0ZLp0OvlOdYxpP5XvRS6Snno/s1600/Gleam.png" width="225" /></a></div><br /><p></p><p>import gleam/io</p><p>import gleam/float</p><p><br /></p><p>pub fn main() {</p><p> // Float arithmetic</p><p> io.debug(1.0 +. 1.5)</p><p> io.debug(5.0 -. 1.5)</p><p> io.debug(5.0 /. 2.5)</p><p> io.debug(3.0 *. 3.5)</p><p><br /></p><p> // Float comparisons</p><p> io.debug(2.2 >. 1.3)</p><p> io.debug(2.2 <. 1.3)</p><p> io.debug(2.2 >=. 1.3)</p><p> io.debug(2.2 <=. 1.3)</p><p><br /></p><p> // Equality works for any type</p><p> io.debug(1.1 == 1.1)</p><p> io.debug(2.1 == 1.2)</p><p><br /></p><p> // Division by zero is not an error</p><p> io.debug(3.14 /. 0.0)</p><p><br /></p><p> // Standard library float functions</p><p> io.debug(float.max(2.0, 9.5))</p><p> io.debug(float.ceiling(5.4))</p><p>}</p><p><br /></p><p>El tipo Float de Gleam representa números que no son enteros.</p><p>Los operadores numéricos de Gleam no están sobrecargados, por lo que existen operadores dedicados para trabajar con flotantes.</p><p>Los flotantes se representan como números de punto flotante de 64 bits tanto en Erlang como de JavaScript. El comportamiento del punto flotante es nativo de sus respectivos runtimes, por lo que su comportamiento exacto será ligeramente diferente en los dos runtimes.</p><p>En JavaScript, exceder el valor máximo (o mínimo) representable para un valor de punto flotante dará como resultado Infinity (o -Infinity). Si intentas dividir dos infinitos, obtendrás NaN como resultado.</p><p>Cuando se ejecuta en BEAM, cualquier desbordamiento generará un error. Por lo tanto, no hay ningún valor flotante NaN o Infinity en el tiempo de ejecución de Erlang.</p><p>La división por cero no se desbordará, sino que se define como cero.</p><p>El módulo de biblioteca estándar gleam/float contiene funciones para trabajar con flotantes.</p><div><br /></div>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-71293289617668440592024-03-04T01:52:00.001-03:002024-03-04T01:52:50.684-03:00Manipular datos binarios con Erlang <p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpMTJltBMq-qYmZ6f1TEkGgODGYQeOzWS1nqraOEmK9bedx_3lultCzL9dk1B9Npo4fRXfLIJHhRRYaIOAQ2Irpt69iXbmC5baMzAxxAa7ciAXHc8I2jYLxe8bslg6uC63PIwD9nVHxOmcfxn4vKNMhgEqAabb8XC4wl4_9KjxOH5S0lNJMnyv0Hx2qng/s512/erlang_logo_icon_169196.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="256" data-original-width="512" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpMTJltBMq-qYmZ6f1TEkGgODGYQeOzWS1nqraOEmK9bedx_3lultCzL9dk1B9Npo4fRXfLIJHhRRYaIOAQ2Irpt69iXbmC5baMzAxxAa7ciAXHc8I2jYLxe8bslg6uC63PIwD9nVHxOmcfxn4vKNMhgEqAabb8XC4wl4_9KjxOH5S0lNJMnyv0Hx2qng/s320/erlang_logo_icon_169196.png" width="320" /></a></div><br />La mayoría de los lenguajes admiten la manipulación de datos como números, átomos, tuplas, listas, registros y/o estructuras, etc. La mayoría de ellos también solo tienen funciones muy básicas para manipular datos binarios. Erlang hace todo lo posible para proporcionar abstracciones útiles cuando se trata de valores binarios con coincidencia de patrones llevada al siguiente nivel. Hace que tratar con datos binarios sin procesar sea divertido y fácil, lo cual era necesario para las aplicaciones de telecomunicaciones para las que fue creado. La manipulación de bits tiene una sintaxis y modismos únicos que pueden parecer un poco extraños al principio, pero si sabes cómo funcionan generalmente los bits y los bytes, esto debería tener sentido. <p></p><p>La sintaxis de bits encierra datos binarios entre << y >>, los divide en segmentos legibles y cada segmento está separado por una coma. Un segmento es una secuencia de bits de un binario (no necesariamente en un límite de bytes, aunque este es el comportamiento predeterminado). Digamos que queremos almacenar un píxel naranja (24 bits). Si alguna vez comprobó los colores en Photoshop o en una hoja de estilos CSS para la web, sabrá que la notación hexadecimal tiene el formato #RRGGBB. Un tinte naranja es #F09A29 en esa notación, que podría ampliarse en Erlang a:</p><p><br /></p><p>1> Color = 16#F09A29.</p><p>15768105</p><p>2> Pixel = <<Color:24>>.</p><p><<240,154,41>></p><p><br /></p><p>Básicamente dice "Coloque los valores binarios de #F09A29 en 24 bits (rojo en 8 bits, verde en 8 bits y azul también en 8 bits) en la variable Píxel". Posteriormente se puede tomar el valor para escribirlo en un archivo. Esto no parece mucho, pero una vez escrito en un archivo, lo que obtendría al abrirlo en un editor de texto sería un montón de caracteres ilegibles. Cuando vuelva a leer el archivo, Erlang interpretará el binario en el bonito formato <<240,151,41>> nuevamente.</p><p>Lo que es más interesante es la capacidad de hacer coincidir patrones con archivos binarios para descomprimir contenido:</p><p><br /></p><p>3> Pixels = <<213,45,132,64,76,32,76,0,0,234,32,15>>.</p><p><<213,45,132,64,76,32,76,0,0,234,32,15>></p><p>4> <<Pix1,Pix2,Pix3,Pix4>> = Pixels.</p><p>** exception error: no match of right hand side value <<213,45,132,64,76,32,76,</p><p>0,0,234,32,15>></p><p>5> <<Pix1:24, Pix2:24, Pix3:24, Pix4:24>> = Pixels.</p><p><<213,45,132,64,76,32,76,0,0,234,32,15>></p><p><br /></p><p>Lo que hicimos en el comando 3 fue declarar lo que serían exactamente 4 píxeles de colores RGB en binario.</p><p>En la expresión 4, intentamos descomprimir 4 valores del contenido binario. Lanza una excepción, porque tenemos más de 4 segmentos, ¡de hecho tenemos 12! Entonces, lo que hacemos es decirle a Erlang que cada variable del lado izquierdo contendrá 24 bits de datos. Eso es lo que significa Var:24. Luego podemos tomar el primer píxel y descomprimirlo en valores de un solo color:</p><p><br /></p><p>6> <<R:8, G:8, B:8>> = <<Pix1:24>>.</p><p><<213,45,132>></p><p>7> R.</p><p>213</p><p><br /></p><p>"Sí, eso es genial. ¿Y si solo quisiera el primer color desde el principio? ¿Tendré que descomprimir todos estos valores todo el tiempo?" ¡Ja! ¡No lo dudes! Erlang introduce más azúcar sintáctico y coincidencia de patrones para ayudarte con:</p><p><br /></p><p>8> <<R:8, Rest/binary>> = Pixels.</p><p><<213,45,132,64,76,32,76,0,0,234,32,15>></p><p>9> R.</p><p>213</p><p><br /></p><p>Bonito, ¿eh? Esto se debe a que Erlang acepta más de una forma de describir un segmento binario. Todos estos son válidos:</p><p><br /></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>Value</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>Value:Size</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>Value/TypeSpecifierList</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>Value:Size/TypeSpecifierList</span></p><p><span style="white-space: normal;"><br /></span></p><p>donde Tamaño representará bits o bytes (según el Tipo y Unidad a continuación) y TypeSpecifierList representa uno o más de los siguientes:</p><p>integer | float | binary | bytes | bitstring | bits | utf8 | utf16 | utf32</p><p>Esto representa el tipo de datos binarios utilizados. Tenga en cuenta que "bytes" es la abreviatura de "binario" y "bits" es la abreviatura de "cadena de bits". Cuando no se especifica ningún tipo, Erlang asume un tipo "entero".</p><p>Firma</p><p>Valores posibles: signed | unsigned</p><p>Solo importa para la coincidencia cuando el tipo es un número entero. El valor predeterminado es "sin firmar".</p><p>Endianidad</p><p>Valores posibles: big | little | native</p><p>La endianidad solo importa cuando el tipo es entero, utf16, utf32 o flotante. Esto tiene que ver con cómo el sistema lee los datos binarios. Como ejemplo, el formato de encabezado de imagen BMP mantiene el tamaño de su archivo como un número entero almacenado en 4 bytes. Para un archivo que tiene un tamaño de 72 bytes, un sistema little-endian lo representaría como <<72,0,0,0>> y uno big-endian como <<0,0,0,72>>. Uno se leerá como '72' mientras que el otro se leerá como '1207959552', así que asegúrese de utilizar el endianismo correcto. También existe la opción de usar 'nativo', que elegirá en tiempo de ejecución si la CPU usa little endianness o big endianness de forma nativa. De forma predeterminada, la endianidad está establecida en "grande".</p><p>Unidad</p><p>unidad unit:Integer</p><p>Este es el tamaño de cada segmento, en bits. El rango permitido es 1..256 y está establecido de forma predeterminada en 1 para números enteros, flotantes y cadenas de bits y en 8 para binarios. Los tipos utf8, utf16 y utf32 no requieren que se defina ninguna unidad. La multiplicación de Tamaño por Unidad es igual a la cantidad de bits que tomará el segmento y debe ser divisible por 8. El tamaño de la unidad generalmente se usa para garantizar la alineación de bytes.</p><p>TypeSpecifierList se construye separando los atributos por un '-'.</p><p><br /></p><p></p><p>Algunos ejemplos pueden ayudar a digerir las definiciones:</p><p><br /></p><p>10> <<X1/unsigned>> = <<-44>>.</p><p><<"Ô">></p><p>11> X1.</p><p>212</p><p>12> <<X2/signed>> = <<-44>>. </p><p><<"Ô">></p><p>13> X2.</p><p>-44</p><p>14> <<X2/integer-signed-little>> = <<-44>>.</p><p><<"Ô">></p><p>15> X2.</p><p>-44</p><p>16> <<N:8/unit:1>> = <<72>>.</p><p><<"H">></p><p>17> N.</p><p>72</p><p>18> <<N/integer>> = <<72>>.</p><p><<"H">></p><p>19> <<Y:4/little-unit:8>> = <<72,0,0,0>>. </p><p><<72,0,0,0>></p><p>20> Y.</p><p>72</p><p><br /></p><p>Puede ver que hay más de una forma de leer, almacenar e interpretar datos binarios. Esto es un poco confuso, pero aún así es mucho más sencillo que utilizar las herramientas habituales que ofrecen la mayoría de los lenguajes.</p><p>Las operaciones binarias estándar (desplazamiento de bits a izquierda y derecha, 'y' binario, 'o', 'xor' o 'no') también existen en Erlang. Simplemente use las funciones bsl (Bit Shift Left), bsr (Bit Shift Right), band, bor, bxor y bnot.</p><p><br /></p><p>2#00100 = 2#00010 bsl 1.</p><p>2#00001 = 2#00010 bsr 1.</p><p>2#10101 = 2#10001 bor 2#00101.</p><div><br /></div><div>Con ese tipo de notación y la sintaxis de bits en general, el análisis y la coincidencia de patrones de datos binarios es pan comido. Se podrían analizar segmentos TCP con un código como este:</div><div><br /></div><div><div><<SourcePort:16, DestinationPort:16,</div><div>AckNumber:32,</div><div>DataOffset:4, _Reserved:4, Flags:8, WindowSize:16,</div><div>CheckSum: 16, UrgentPointer:16,</div><div>Payload/binary>> = SomeBinary.</div></div><div><br /></div><div><div>La misma lógica se puede aplicar a cualquier cosa binaria: codificación de vídeo, imágenes, otras implementaciones de protocolos, etc.</div><div><br /></div><div>Erlang es lento en comparación con lenguajes como C o C++. A menos que seas una persona paciente, sería una mala idea hacer cosas como convertir vídeos o imágenes con él, aunque la sintaxis binaria lo hace extremadamente interesante, como insinué anteriormente. Erlang simplemente no es tan bueno para hacer cálculos numéricos intensos.</div><div><br /></div><div>Tenga en cuenta, sin embargo, que Erlang sigue siendo muy rápido para aplicaciones que no requieren cálculos numéricos: reaccionar a eventos, pasar mensajes (con la ayuda de átomos que son extremadamente livianos), etc. Puede manejar eventos en cuestión de milisegundos y como Este es un gran candidato para aplicaciones suaves en tiempo real.</div><div><br /></div><div>Hay un aspecto completamente diferente en la notación binaria: las cadenas de bits. Las cadenas binarias están atornilladas encima del lenguaje de la misma manera que con las listas, pero son mucho más eficientes en términos de espacio. Esto se debe a que las listas normales son listas enlazadas (1 'nodo' por letra), mientras que las cadenas de bits se parecen más a matrices C. Las cadenas de bits utilizan la sintaxis <<"¡esta es una cadena de bits!">>. La desventaja de las cadenas binarias en comparación con las listas es la pérdida de simplicidad cuando se trata de coincidencia y manipulación de patrones. En consecuencia, la gente tiende a utilizar cadenas binarias cuando almacenan texto que no será manipulado demasiado o cuando la eficiencia del espacio es un problema real.</div><div><br /></div><div>Nota: Aunque las cadenas de bits son bastante ligeras, debes evitar usarlas para etiquetar valores. Podría resultar tentador utilizar cadenas literales para decir {<<"temperatura">>,50}, pero siempre utilice átomos al hacerlo. Anteriormente, se decía que los átomos ocupaban sólo 4 u 8 bytes en el espacio, sin importar su longitud. Al usarlos, básicamente no tendrá gastos generales al copiar datos de una función a otra o enviarlos a otro nodo Erlang en otro servidor.</div><div>Por el contrario, no utilice átomos para reemplazar cadenas porque son más ligeras. Las cadenas se pueden manipular (división, expresiones regulares, etc.), mientras que los átomos sólo se pueden comparar y nada más.</div></div>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-86354652388529120122024-03-02T15:06:00.000-03:002024-03-02T15:06:00.151-03:00El tipo Int de Gleam<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfquIQGEGBuUTEMJFs11mZyU0eulqagu-gahDCy4K4O77od7OuvXYUsaupQ3zAVVXyqmM1wjyNf-LCEsJZJu7YyOspDTmfCRaXFWwCO9MpU202deZinMm7ypCL3cRuLD1cNNfKSBrQu6MYzmlKWJqrvf8WxYTIUlOWfaI0ZLp0OvlOdYxpP5XvRS6Snno/s225/Gleam.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="225" data-original-width="225" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfquIQGEGBuUTEMJFs11mZyU0eulqagu-gahDCy4K4O77od7OuvXYUsaupQ3zAVVXyqmM1wjyNf-LCEsJZJu7YyOspDTmfCRaXFWwCO9MpU202deZinMm7ypCL3cRuLD1cNNfKSBrQu6MYzmlKWJqrvf8WxYTIUlOWfaI0ZLp0OvlOdYxpP5XvRS6Snno/s1600/Gleam.png" width="225" /></a></div><br />import gleam/io<p></p><p>import gleam/int</p><p><br /></p><p>pub fn main() {</p><p> // Int arithmetic</p><p> io.debug(1 + 1)</p><p> io.debug(5 - 1)</p><p> io.debug(5 / 2)</p><p> io.debug(3 * 3)</p><p> io.debug(5 % 2)</p><p><br /></p><p> // Int comparisons</p><p> io.debug(2 > 1)</p><p> io.debug(2 < 1)</p><p> io.debug(2 >= 1)</p><p> io.debug(2 <= 1)</p><p><br /></p><p> // Equality works for any type</p><p> io.debug(1 == 1)</p><p> io.debug(2 == 1)</p><p><br /></p><p> // Standard library int functions</p><p> io.debug(int.max(42, 77))</p><p> io.debug(int.clamp(5, 10, 20))</p><p>}</p><div>El tipo Int de Gleam representa números enteros.</div><p>Existen operadores aritméticos y de comparación para enteros, así como el operador de igualdad que funciona en todos los tipos.</p><p>Cuando se ejecuta en la máquina virtual Erlang, los ints no tienen un tamaño máximo ni mínimo. Cuando se ejecuta en JavaScript, los ints se representan utilizando números de punto flotante de 64 bits de JavaScript,</p><p>El módulo de biblioteca estándar gleam/int contiene funciones para trabajar con ints.</p>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-46295816888823893192024-03-01T06:18:00.000-03:002024-03-01T06:18:52.503-03:00Sistema de tipo en Gleam<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizPxI1WQ-2hfcPlS_qrP-X7Rucygn5KXFJPqx22XWEF2A2X_ve8cvlO2hFxugs_-mGamZYo2335YiyY5imL7h_jt5ufLjiLlv3dsSjJSQ0IQGIMzsGo48OninKTas_qn6p3zvxg6HttRRnNXHK51qzFqygD0F2O133_7Zwye9e0_fGiyQBg21ZHvpqFIc/s225/Gleam.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="225" data-original-width="225" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizPxI1WQ-2hfcPlS_qrP-X7Rucygn5KXFJPqx22XWEF2A2X_ve8cvlO2hFxugs_-mGamZYo2335YiyY5imL7h_jt5ufLjiLlv3dsSjJSQ0IQGIMzsGo48OninKTas_qn6p3zvxg6HttRRnNXHK51qzFqygD0F2O133_7Zwye9e0_fGiyQBg21ZHvpqFIc/s1600/Gleam.png" width="225" /></a></div><br /> import gleam/io<p></p><p><br /></p><p>pub fn main() {</p><p> io.println("My lucky number is:")</p><p> // io.println(4)</p><p>}</p><div><br /></div><p><br /></p><p>Gleam tiene un robusto sistema de tipos estáticos que ayuda a escribir y editar código, detectando errores y mostrándole dónde realizar cambios.</p><p>Si descomentamos la línea io.println(4), Gleam lanza el siguiente error:</p><p><br /></p><p>error: Type mismatch</p><p> ┌─ /src/main.gleam:5:14</p><p> │</p><p>5 │ io.println(4)</p><p> │ ^</p><p><br /></p><p>Expected type:</p><p><br /></p><p> String</p><p><br /></p><p>Found type:</p><p><br /></p><p> Int</p><p><br /></p><p>Para corregir el código, podemos cambiar io.println por io.debug, ya que esta función imprime un valor de cualquier tipo.</p><p>import gleam/io</p><p><br /></p><p>pub fn main() {</p><p> io.println("My lucky number is:")</p><p> io.debug(4)</p><p>}</p><div><br /></div><p>Gleam no tiene nulos, ni conversiones implícitas, ni excepciones, y siempre realiza una verificación de tipo completa. Si el código se compila, puede estar razonablemente seguro de que no tendrá inconsistencias que puedan causar errores o fallas.</p>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-16468133408970935422024-02-29T01:25:00.004-03:002024-02-29T01:25:41.684-03:00Listas por comprensión en Erlang<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpMTJltBMq-qYmZ6f1TEkGgODGYQeOzWS1nqraOEmK9bedx_3lultCzL9dk1B9Npo4fRXfLIJHhRRYaIOAQ2Irpt69iXbmC5baMzAxxAa7ciAXHc8I2jYLxe8bslg6uC63PIwD9nVHxOmcfxn4vKNMhgEqAabb8XC4wl4_9KjxOH5S0lNJMnyv0Hx2qng/s512/erlang_logo_icon_169196.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="256" data-original-width="512" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpMTJltBMq-qYmZ6f1TEkGgODGYQeOzWS1nqraOEmK9bedx_3lultCzL9dk1B9Npo4fRXfLIJHhRRYaIOAQ2Irpt69iXbmC5baMzAxxAa7ciAXHc8I2jYLxe8bslg6uC63PIwD9nVHxOmcfxn4vKNMhgEqAabb8XC4wl4_9KjxOH5S0lNJMnyv0Hx2qng/s320/erlang_logo_icon_169196.png" width="320" /></a></div><br /><p>Las listas por comprensión son formas de crear o modificar listas. También hacen que los programas sean breves y fáciles de entender en comparación con otras formas de manipular listas. Se basa en la idea de notación de conjuntos; Si alguna vez has tomado clases de matemáticas con teoría de conjuntos o si alguna vez has estudiado notación matemática, probablemente sepas cómo funciona. La notación de conjuntos básicamente le dice cómo construir un conjunto especificando las propiedades que deben satisfacer sus miembros. La comprensión de las listas puede ser difícil de entender al principio, pero vale la pena el esfuerzo. </p><p>Un ejemplo de notación de conjuntos sería {x ∈ ℜ x = x^2}. Esa notación de conjuntos le indica que los resultados que desea serán todos números reales iguales a su propio cuadrado. El resultado de ese conjunto sería {0,1}. Otro ejemplo de notación de conjuntos, más simple y abreviado sería {x : x > 0}. Aquí, lo que queremos son todos los números donde x > 0.</p><p>Las listas por comprensión en Erlang tratan de construir conjuntos a partir de otros conjuntos. Dado el conjunto {2n : n en L} donde L es la lista [1,2,3,4], la implementación de Erlang sería:</p><p>1> [2*N || N <- [1,2,3,4]].</p><p>[2,4,6,8]</p><p>Si comparamos la notación matemática con la de Erlang y no hay mucho que cambie: las llaves ({}) se convierten en corchetes ([]), los dos puntos (:) se convierten en dos barras verticales (||) y la palabra 'in' se convierte en la flecha. (<-). Sólo cambiamos símbolos y mantenemos la misma lógica. En el ejemplo anterior, cada valor de [1,2,3,4] coincide secuencialmente con el patrón N. La flecha actúa exactamente como el operador =, con la excepción de que no genera excepciones.</p><p>También puede agregar restricciones a la comprensión de una lista mediante operaciones que devuelvan valores booleanos. Si quisiéramos todos los números pares del uno al diez, podríamos escribir algo como:</p><p>2> [X || X <- [1,2,3,4,5,6,7,8,9,10], X rem 2 =:= 0].</p><p>[2,4,6,8,10]</p><p>Donde X rem 2 =:= 0 comprueba si un número es par. Las aplicaciones prácticas surgen cuando decidimos que queremos aplicar una función a cada elemento de una lista, obligándolo a respetar restricciones, etc. Como ejemplo, digamos que somos dueños de un restaurante. Un cliente entra, ve nuestro menú y pregunta si podría tener los precios de todos los artículos que cuestan entre $3 y $10 con los impuestos (digamos 7%) contados después.</p><p>3> RestaurantMenu = [{steak, 5.99}, {beer, 3.99}, {poutine, 3.50}, {kitten, 20.99}, {water, 0.00}].</p><p>[{steak,5.99},</p><p>{beer,3.99},</p><p>{poutine,3.5},</p><p>{kitten,20.99},</p><p>{water,0.0}]</p><p>4> [{Item, Price*1.07} || {Item, Price} <- RestaurantMenu, Price >= 3, Price =< 10].</p><p>[{steak,6.409300000000001},{beer,4.2693},{poutine,3.745}]</p><p><br /></p><p>Por supuesto, los decimales no están redondeados de manera legible, pero entiendes el punto. Por lo tanto, la receta para la comprensión de listas en Erlang es NewList = [Expression || Patrón <- Lista, Condición1, Condición2, ... CondiciónN]. La parte Patrón <- Lista se denomina expresión Generadora. </p><p><br /></p><p>5> [X+Y || X <- [1,2], Y <- [2,3]].</p><p>[3,4,4,5]</p><div><br /></div><div>Esto ejecuta las operaciones 1+2, 1+3, 2+2, 2+3. Entonces, si desea que la receta de comprensión de la lista sea más genérica, obtendrá: NewList = [Expression || GeneradorExp1, GeneradorExp2, ..., GeneradorExpN, Condición1, Condición2, ... CondiciónM]. Tenga en cuenta que las expresiones del generador junto con la coincidencia de patrones también actúan como filtro:</div><div><br /></div><div><div>6> Weather = [{toronto, rain}, {montreal, storms}, {london, fog}, </div><div>6> {paris, sun}, {boston, fog}, {vancouver, snow}].</div><div>[{toronto,rain},</div><div>{montreal,storms},</div><div>{london,fog},</div><div>{paris,sun},</div><div>{boston,fog},</div><div>{vancouver,snow}]</div><div>7> FoggyPlaces = [X || {X, fog} <- Weather].</div><div>[london,boston]</div></div><div><br /></div><div><div>Si un elemento de la lista 'Clima' no coincide con el patrón {X, niebla}, simplemente se ignora en la comprensión de la lista, mientras que el operador = habría generado una excepción.</div><div><br /></div></div>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-64306230065860992572024-02-26T00:17:00.002-03:002024-02-26T00:17:47.024-03:00Imports en gleam<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizPxI1WQ-2hfcPlS_qrP-X7Rucygn5KXFJPqx22XWEF2A2X_ve8cvlO2hFxugs_-mGamZYo2335YiyY5imL7h_jt5ufLjiLlv3dsSjJSQ0IQGIMzsGo48OninKTas_qn6p3zvxg6HttRRnNXHK51qzFqygD0F2O133_7Zwye9e0_fGiyQBg21ZHvpqFIc/s225/Gleam.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="225" data-original-width="225" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizPxI1WQ-2hfcPlS_qrP-X7Rucygn5KXFJPqx22XWEF2A2X_ve8cvlO2hFxugs_-mGamZYo2335YiyY5imL7h_jt5ufLjiLlv3dsSjJSQ0IQGIMzsGo48OninKTas_qn6p3zvxg6HttRRnNXHK51qzFqygD0F2O133_7Zwye9e0_fGiyQBg21ZHvpqFIc/s1600/Gleam.png" width="225" /></a></div><br />// Import the module and one of its functions<p></p><p>import gleam/io.{println}</p><p><br /></p><p>pub fn main() {</p><p> // Use the function in a qualified fashion</p><p> io.println("This is qualified")</p><p><br /></p><p> // Or an unqualified fashion</p><p> println("This is unqualified")</p><p>}</p><div><br /></div><p>Normalmente, las funciones de otros módulos se utilizan de forma calificada, con el calificador del módulo antes del nombre de la función. Por ejemplo, io.println("¡Hola!").</p><p>También es posible especificar una lista de funciones para importar desde un módulo de forma no calificada, como la función println en el editor de código. Debido a que se importó de esta manera, se le puede llamar simplemente println.</p><p>Generalmente es mejor utilizar importaciones calificadas, ya que esto deja claro dónde está definida la función, lo que hace que el código sea más fácil de leer.</p>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-73951623654353633272024-02-26T00:10:00.000-03:002024-02-26T00:10:52.804-03:00Hello world en Gleam<p> </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7VB7_ezs1vWxYyOSpJDiJdeweL-8IG-xXZO93cBGT0wV0Z34rZVKPfYpvGJGfVkRjY70Arx7W9nBL_ffLYTVqHc06H8if3QK2ODK5jghk9rLv5uQg0itRsDLhcBLPTm-XH0AEAwvm6eHewvysMBLGLb8xKq-hbaQnLkOPCJqgTFJXDs4xU7rhj-NIJG0/s225/Gleam.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="225" data-original-width="225" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7VB7_ezs1vWxYyOSpJDiJdeweL-8IG-xXZO93cBGT0wV0Z34rZVKPfYpvGJGfVkRjY70Arx7W9nBL_ffLYTVqHc06H8if3QK2ODK5jghk9rLv5uQg0itRsDLhcBLPTm-XH0AEAwvm6eHewvysMBLGLb8xKq-hbaQnLkOPCJqgTFJXDs4xU7rhj-NIJG0/s1600/Gleam.png" width="225" /></a></div><br />// Import a Gleam module from the standard library<p></p><p>import gleam/io</p><p><br /></p><p>pub fn main() {</p><p> // Print to the console</p><p> io.println("Hello world!")</p><p>}</p><p><br /></p><p>Aquí hay un programa que imprime el texto "Hello world!".</p><p>Para ello, utiliza la función println que se ha importado del módulo gleam/io, que forma parte de la biblioteca estándar de Gleam.</p><p>Para ejecutar este programa se usa el comando gleam run.</p><p><br /></p>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-38105551722915830142024-02-25T23:57:00.000-03:002024-02-25T23:57:08.218-03:00Instalando go zero<p> </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9Kanq9AU9JMepii1iiM84I2wSHjWGN3tOQ-5CfRvSRlcOj9hoDLM-Lwc9RoOoyAKH8xK_1HIufgQVMNMelFu_p-1MaqcQ77O6u8IgIQ6azdvnW0-vu6-poMM-mrWD-O3J8r_WeRQWiOPnRq38gmUgkPlYtq5fEyDuWaebjrJqZSguFEsq83-d1_0c38c/s512/go-zero.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="512" data-original-width="512" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9Kanq9AU9JMepii1iiM84I2wSHjWGN3tOQ-5CfRvSRlcOj9hoDLM-Lwc9RoOoyAKH8xK_1HIufgQVMNMelFu_p-1MaqcQ77O6u8IgIQ6azdvnW0-vu6-poMM-mrWD-O3J8r_WeRQWiOPnRq38gmUgkPlYtq5fEyDuWaebjrJqZSguFEsq83-d1_0c38c/s320/go-zero.png" width="320" /></a></div><br /><a href="https://emanuelpeg.blogspot.com/2023/12/que-es-go-zero.html" target="_blank">Ya hemos hablado de zero el framework de go</a> para hacer microservicios. Ahora vamos a bajar las herramientas para trabajar con él. <p></p><p>Primero, tenemos que tener go instalado. Yo tengo la versión 1.22.0</p><p>$ go version</p><p>go version go1.22.0 linux/amd64</p><div><br /></div><div>Después de la versión 1.11, se recomienda que el valor GO111MODULE se establezca en on para evitar errores innecesarios.</div><div><br /></div><div>$ go env -w GO111MODULE=on</div><div>$ go env -w GOPROXY=https://goproxy.cn,direct</div><div><br /></div><div><div>$ go env GO111MODULE</div><div>on</div><div>$ go env GOPROXY</div><div>https://goproxy.cn,direct</div></div><div><br /></div><div>goctl es una herramienta incorporada de go-zero que es importante para aumentar la eficiencia del desarrollo, generar código, documentos, implementar k8s yaml, dockerfile, etc.</div><div><br /></div><div><div>$ go install github.com/zeromicro/go-zero/tools/goctl@latest</div><div>go: downloading github.com/gookit/color v1.5.4</div><div>go: downloading github.com/withfig/autocomplete-tools/integrations/cobra v1.2.1</div><div>go: downloading github.com/spf13/cobra v1.8.0</div></div><div>...</div><div><br /></div><div><div>$ goctl -version</div><div>goctl version 1.6.2 linux/amd64</div></div><div><br /></div><div>Ahora tenemos que installar docker. Yo ya tengo docker instalado por lo tanto siguo: </div><div><br /></div><div><div>$ sudo docker pull kevinwan/goctl</div><div>$ sudo docker run --rm -it -v `pwd`:/app kevinwan/goctl goctl --help</div></div><div><br /></div><div>Y si todo anda bien hacemos : </div><div><br /></div><div><div>$ sudo docker run --rm -it -v `pwd`:/app kevinwan/goctl:latest goctl --version</div><div>goctl version 1.3.5 linux/amd64</div></div><div><br /></div><div>protoc es una herramienta para generar código basado en archivos proto, este genern código en múltiples lenguajes como C++, Java, Python, Go, PHP, etc. para nuestros servicios gRPC. Lo tenemos que instalar, en mi caso yo lo tenia instalado y lo sé porque hice : </div><div><br /></div><div><div>$ goctl env check --install --verbose --force</div><div>[goctl-env]: preparing to check env</div><div><br /></div><div>[goctl-env]: looking up "protoc"</div><div>[goctl-env]: "protoc" is installed</div><div><br /></div><div>[goctl-env]: looking up "protoc-gen-go"</div><div>[goctl-env]: "protoc-gen-go" is installed</div><div><br /></div><div>[goctl-env]: looking up "protoc-gen-go-grpc"</div><div>[goctl-env]: "protoc-gen-go-grpc" is installed</div><div><br /></div><div>[goctl-env]: congratulations! your goctl environment is ready!</div></div><div><br /></div><div>Y ahora por fin, vamos a crear nuestro proyecto go-zero!! </div><div><br /></div><div>Creamos el proyecto: </div><div><div>$ mkdir myapp && cd myapp</div><div>$ go mod init myapp</div></div><div><div>$ go get github.com/zeromicro/go-zero@latest</div><div>go: added github.com/zeromicro/go-zero v1.6.2</div></div><div><br /></div><div><br /></div><div>Y Listo!! </div><div><br /></div><div><br /></div>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-52133231908324410912024-02-24T11:37:00.000-03:002024-02-24T11:37:49.795-03:00Gleam Language Tour<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizPxI1WQ-2hfcPlS_qrP-X7Rucygn5KXFJPqx22XWEF2A2X_ve8cvlO2hFxugs_-mGamZYo2335YiyY5imL7h_jt5ufLjiLlv3dsSjJSQ0IQGIMzsGo48OninKTas_qn6p3zvxg6HttRRnNXHK51qzFqygD0F2O133_7Zwye9e0_fGiyQBg21ZHvpqFIc/s225/Gleam.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="225" data-original-width="225" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizPxI1WQ-2hfcPlS_qrP-X7Rucygn5KXFJPqx22XWEF2A2X_ve8cvlO2hFxugs_-mGamZYo2335YiyY5imL7h_jt5ufLjiLlv3dsSjJSQ0IQGIMzsGo48OninKTas_qn6p3zvxg6HttRRnNXHK51qzFqygD0F2O133_7Zwye9e0_fGiyQBg21ZHvpqFIc/s1600/Gleam.png" width="225" /></a></div><br />Como tengo tanto tiempo y siempre viene bien aprender un nuevo lenguaje, voy a hacer el Gleam Language Tour. <p></p><p>Ya he hablado de Gleam en <a href="https://emanuelpeg.blogspot.com/2023/03/gleam-un-lenguaje-funcional-que-corre.html" target="_blank">otro post</a> y no me quiero repetir. Les comparto el link y los invito a hacerlo conmigo. </p><p>Dejo link: <a href="https://tour.gleam.run/basics/hello-world/">https://tour.gleam.run/basics/hello-world/</a></p>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-9994984036221789852024-02-22T01:41:00.000-03:002024-02-22T01:41:28.762-03:00Listas en Erlang<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQogTAMjhdP7yzmPbEzoljr1QjbXvQ-F10L40Jx7Tvz28vOyf0bmwX0xLPcXo69HzDZI5X-CaymHNb82DizyOMyscI6puLFByaxPUZZyHxEploo8vo8XXc0D6QBBc11R4LSt4MxvX6xuxwHtt_OEZdny2QlKrUT91FbUj8_8sOxX2QagNvqAkwZZ3Dn60/s512/erlang_logo_icon_169196.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="256" data-original-width="512" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQogTAMjhdP7yzmPbEzoljr1QjbXvQ-F10L40Jx7Tvz28vOyf0bmwX0xLPcXo69HzDZI5X-CaymHNb82DizyOMyscI6puLFByaxPUZZyHxEploo8vo8XXc0D6QBBc11R4LSt4MxvX6xuxwHtt_OEZdny2QlKrUT91FbUj8_8sOxX2QagNvqAkwZZ3Dn60/s320/erlang_logo_icon_169196.png" width="320" /></a></div><br />Las listas se utilizan para resolver todo tipo de problemas y son sin duda la estructura de datos más utilizada en Erlang. ¡Las listas pueden contener cualquier cosa! Números, átomos, tuplas, otras listas. La notación básica de una lista es [Elemento1, Elemento2,..., ElementoN] y puedes mezclar más de un tipo de datos en ella:<p></p><p><br /></p><p>> [1, 2, 3, {numbers,[4,5,6]}, 5.34, atom].</p><p>[1,2,3,{numbers,[4,5,6]},5.34,atom]</p><p><br /></p><div>Bastante simple, ¿verdad?</div><div><br /></div><div><div>2> [97, 98, 99].</div><div>"abc"</div></div><div><br /></div><div>Los strings son listas y la notación es absolutamente la misma ¿Por qué a la gente no le gusta? Debido a esto:</div><div><br /></div><div><div>3> [97,98,99,4,5,6].</div><div>[97,98,99,4,5,6]</div><div>4> [233].</div><div>"é"</div></div><div><br /></div><div><div>Erlang imprimirá listas de números como números solo cuando al menos uno de ellos no pueda representar como una letra. </div><div><br /></div><div>Es por eso que quizás hayas escuchado que se dice que Erlang es malo en la manipulación de cadenas: no hay un tipo de cadena incorporado como en la mayoría de los otros lenguajes. Esto se debe a los orígenes de Erlang como lenguaje creado y utilizado por empresas de telecomunicaciones. Nunca (o rara vez) usaron cadenas y, como tal, nunca tuvieron ganas de agregarlas oficialmente. Sin embargo, la mayor parte de la falta de sentido de Erlang en las manipulaciones de cadenas se está solucionando con el tiempo: la máquina virtual ahora admite de forma nativa cadenas Unicode y, en general, se vuelve más rápida en las manipulaciones de cadenas todo el tiempo.</div><div><br /></div><div>También hay una manera de almacenar cadenas como una estructura de datos binarios, lo que las hace realmente livianas y más rápidas para trabajar. Con todo, todavía faltan algunas funciones en la biblioteca estándar y, si bien el procesamiento de cadenas es definitivamente factible en Erlang, existen lenguajes algo mejores para tareas que necesitan mucho, como Perl o Python.</div><div><br /></div><div>Para unir listas, usamos el operador ++. Lo opuesto a ++ es -- y eliminará elementos de una lista:</div></div><div><br /></div><div><div>5> [1,2,3] ++ [4,5].</div><div>[1,2,3,4,5]</div><div>6> [1,2,3,4,5] -- [1,2,3].</div><div>[4,5]</div><div>7> [2,4,2] -- [2,4].</div><div>[2]</div><div>8> [2,4,2] -- [2,4,2].</div><div>[]</div></div><div><br /></div><div><div>Tanto ++ como -- son asociativos por la derecha. Esto significa que los elementos de muchas operaciones -- o ++ se realizarán de derecha a izquierda, como en los siguientes ejemplos:</div><div><br /></div><div>9>[1,2,3]-[1,2]-[3].</div><div>[3]</div><div>10>[1,2,3]-[1,2]-[2].</div><div>[2,3]</div><div><br /></div><div>El primer elemento de una lista se denomina Encabezado y el resto de la lista se denomina Cola. Usaremos dos funciones integradas (BIF) para obtenerlas.</div><div><br /></div><div>11> hd([1,2,3,4]).</div><div>1</div><div>12>tl([1,2,3,4]).</div><div>[2,3,4]</div></div><div><br /></div><div><div>Las funciones integradas (BIF) suelen ser funciones que no se pueden implementar en Erlang puro y, como tales, se definen en C, o en cualquier lenguaje en el que se implemente Erlang (era Prolog en los años 80). Todavía hay algunos BIF que se pueden realizar en Erlang pero que aún se implementaron en C para proporcionar más velocidad a las operaciones comunes. Un ejemplo de esto es la función length(List), que devolverá la longitud (lo has adivinado) de la lista pasada como argumento.</div><div><br /></div><div>Como se usa con tanta frecuencia, existe una forma más sencilla de separar el principio del final de una lista con la ayuda de la coincidencia de patrones: [Cabeza|Cola]. Así es como agregarías un nuevo encabezado a una lista:</div><div><br /></div><div>13> Lista = [2,3,4].</div><div>[2,3,4]</div><div>14>NuevaLista = [1|Lista].</div><div>[1,2,3,4]</div><div><br /></div><div>Al procesar listas, como normalmente se comienza con la cabeza, podemos desear una forma rápida de almacenar también la cola para operarla más tarde. Si recuerdas la forma en que funcionan las tuplas y cómo usamos la coincidencia de patrones para descomprimir los valores de un punto ({X,Y}), sabrás que podemos cortar el primer elemento (el encabezado) de una lista de manera similar. .</div><div><br /></div><div>15> [Cabeza|Cola] = NuevaLista.</div><div>[1,2,3,4]</div><div>16> Cabeza.</div><div>1</div><div>17> Cola.</div><div>[2,3,4]</div><div>18> [NuevaCabeza|NuevaCola] = Cola.</div><div>[2,3,4]</div><div>19> Nuevo jefe.</div><div>2</div><div><br /></div><div>El | que utilizamos se llama operador de contras (constructor). De hecho, cualquier lista se puede construir sólo con el operador:</div><div><br /></div><div>20> [1 | []].</div><div>[1]</div><div>21> [2 | [1 | []]].</div><div>[2,1]</div><div>22> [3 | [2 | [1 | []] ] ].</div><div>[3,2,1]</div><div><br /></div><div>Es decir cualquier lista se puede construir con la siguiente fórmula: [Término1| [Término2 | [... | [TérminoN]]]].... Las listas pueden así definirse recursivamente como un principio que precede a un final, que a su vez es un principio seguido de más principios. En este sentido, podríamos imaginar una lista como una lombriz de tierra: puedes cortarla por la mitad y luego tendrás dos lombrices.</div></div><div><br /></div><div><div>Las formas en que se pueden construir las listas de Erlang a veces resultan confusas para las personas que no están acostumbradas a constructores similares. Para ayudarle a familiarizarse con el concepto, lea todos estos ejemplos (pista: todos son equivalentes):</div><div><br /></div><div>[a B C D]</div><div>[a, b, c, d | []]</div><div>[a, b | [cd]]</div><div>[a, b | [c | [d]]]</div><div>[un | [b | [c | [d]]]]</div><div>[un | [b | [c | [d | [] ]]]]</div><div><br /></div><div>Una vez entendido esto, debería poder lidiar con listas por comprensión.</div><div><br /></div><div>Usando el formulario [1 | 2] ofrece lo que llamamos una "lista inadecuada". Las listas inadecuadas funcionarán cuando coincida el patrón en la forma [Cabeza|Cola], pero no podrán usarse con funciones estándar de Erlang (longitud uniforme()). Esto se debe a que Erlang espera listas adecuadas. Las listas adecuadas terminan con una lista vacía como última celda. Al declarar un elemento como [2], la lista se forma automáticamente de manera adecuada. ¡Como tal, [1|[2]] funcionaría! Las listas inadecuadas, aunque sintácticamente válidas, tienen un uso muy limitado fuera de las estructuras de datos definidas por el usuario.</div></div>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-57339388872967956802024-02-18T23:31:00.001-03:002024-02-18T23:31:16.559-03:00Quickysort en Erlang<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQogTAMjhdP7yzmPbEzoljr1QjbXvQ-F10L40Jx7Tvz28vOyf0bmwX0xLPcXo69HzDZI5X-CaymHNb82DizyOMyscI6puLFByaxPUZZyHxEploo8vo8XXc0D6QBBc11R4LSt4MxvX6xuxwHtt_OEZdny2QlKrUT91FbUj8_8sOxX2QagNvqAkwZZ3Dn60/s512/erlang_logo_icon_169196.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="256" data-original-width="512" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQogTAMjhdP7yzmPbEzoljr1QjbXvQ-F10L40Jx7Tvz28vOyf0bmwX0xLPcXo69HzDZI5X-CaymHNb82DizyOMyscI6puLFByaxPUZZyHxEploo8vo8XXc0D6QBBc11R4LSt4MxvX6xuxwHtt_OEZdny2QlKrUT91FbUj8_8sOxX2QagNvqAkwZZ3Dn60/s320/erlang_logo_icon_169196.png" width="320" /></a></div><br />Un Algoritmo que me gusta mucho es el quicksort, porque es un algoritmo por demás claro. Ya he escrito lo fácil que es implementarlo en <a href="https://emanuelpeg.blogspot.com/2024/02/quicksort-en-rust.html" target="_blank">Rust</a>, <a href="https://emanuelpeg.blogspot.com/2016/04/quicksort-en-haskell.html" target="_blank">haskell</a> y <a href="https://emanuelpeg.blogspot.com/2023/11/quicksort-in-lisp.html" target="_blank">lisp</a><p></p><p>Ahora le toca a Erlang. Básicamente el algoritmo toma un pivot y agrupa los menores del pivot al principio y los mayores al final y aplica quicksort a estos 2 grupos. Y si la lista es vacia o tiene un elemento, ya esta ordenada. </p><p>Vamos al código: </p><p><br /></p><p>sort([Pivot|T]) -></p><p> sort([ X || X <- T, X < Pivot]) ++</p><p> [Pivot] ++</p><p> sort([ X || X <- T, X >= Pivot]);</p><p>sort([]) -> [].</p><p><br /></p><p>Y listo!!</p>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-58158664101939540622024-02-16T06:41:00.003-03:002024-02-16T06:41:54.843-03:00Chequeando "TODOs" con Roslyn<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3lDcpDOjq6mgB4s5H9twipKycu2fIiSSA-gf9l5HvjNVKzqUlkndubgPAor16yeJRhbAQYJeLNvLtAPRYNfE5q1YloyjHu6HIvj54s4z81Ix5anP5T_4OFbgLO5uL7YQLa0b2hXFGmgIJUNSiac-rE3UDoib04d0fLw8YDAAQea-O41U64xoniz9jVFc/s1200/Roslyn.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="665" data-original-width="1200" height="355" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3lDcpDOjq6mgB4s5H9twipKycu2fIiSSA-gf9l5HvjNVKzqUlkndubgPAor16yeJRhbAQYJeLNvLtAPRYNfE5q1YloyjHu6HIvj54s4z81Ix5anP5T_4OFbgLO5uL7YQLa0b2hXFGmgIJUNSiac-rE3UDoib04d0fLw8YDAAQea-O41U64xoniz9jVFc/w640-h355/Roslyn.png" width="640" /></a></div><br />Vamos a buscar // TODO: ... con Roslyn <p></p><p>Para empezar en una aplicación de consola simple agreguemos algunos paquetes. Microsoft.CodeAnalysis.CSharp y Microsoft.CodeAnalysis.CSharp.Workspaces son lo que necesitamos.</p><p>Y hacemos esto: </p><p><br /></p><p>const int ExitOK = 0;</p><p>const int ExitError = 99;</p><p>const int ExitIssueFound = 1;</p><p><br /></p><p>static async Task<int> MainAsync(string[] args)</p><p>{</p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>var workspace = await GetWorkspace().ConfigureAwait(false);</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>if (workspace == null)</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>return ExitError;</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>using (workspace)</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>{</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>var issueFound = false;</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>foreach (var project in workspace.CurrentSolution.Projects)</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>{</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>foreach (var document in project.Documents)</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>{</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>var documentWritten = false;</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>var root = await document.GetSyntaxRootAsync().ConfigureAwait(false);</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>foreach (var item in root.DescendantTrivia().Where(x => x.IsKind(SyntaxKind.SingleLineCommentTrivia)))</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>{</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>var match = Regex.Match(item.ToFullString(), @"//\s?TODO:\s*(.*)");</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>if (match.Success)</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>{</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>issueFound = true;</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>var text = match.Groups[1].Value;</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>if (!documentWritten)</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>{</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>documentWritten = true;</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>Console.WriteLine(MinimizePath(document.FilePath));</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>}</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>var position = item.GetLocation().GetMappedLineSpan();</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>var line = position.StartLinePosition.Line;</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>Console.WriteLine($"\tL{line}:\t{text}");</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>}</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>}</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>}</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>}</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>return issueFound ? ExitIssueFound : ExitOK;</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>}</span></p><p>}</p><p><br /></p><p>static async Task<Workspace> GetWorkspace()</p><p>{</p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>var workspace = MSBuildWorkspace.Create();</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>var solution = Directory.EnumerateFiles(Environment.CurrentDirectory, "*.sln", SearchOption.TopDirectoryOnly).FirstOrDefault();</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>if (solution != null)</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>{</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>await workspace.OpenSolutionAsync(solution).ConfigureAwait(false);</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>return workspace;</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>}</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>var project = Directory.EnumerateFiles(Environment.CurrentDirectory, "*.csproj", SearchOption.TopDirectoryOnly).FirstOrDefault();</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>if (project != null)</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>{</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>await workspace.OpenProjectAsync(project).ConfigureAwait(false);</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>return workspace;</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>}</span></p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>return null;</span></p><p>}</p><p><br /></p><p>static string MinimizePath(string path)</p><p>{</p><p><span style="white-space: normal;"><span style="white-space: pre;"> </span>return path.Remove(0, Environment.CurrentDirectory.Length + 1);</span></p><p>}</p><p><br /></p>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0tag:blogger.com,1999:blog-6337866978093157247.post-69268533218375332922024-02-14T00:28:00.001-03:002024-02-14T00:28:55.877-03:00Tuplas en Erlang<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL4KSdQnSqpN3E1kJ4d96VsP4ND-q_VO8vVN1VEiEupYwQyI4wtdWKQl4JPUnAwGIR1DIqofdIe9jynrSdUZeuRoQw9y2fWbztZAPZ5fuyTWJoXSoS5NETNnoQq6JhmSL0VtArLhrmIkqvj_p_4p2jsPtoS04XFe1wR7dl9IC3t0VAEGl6gb9fre6T60A/s512/erlang_logo_icon_169196.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="256" data-original-width="512" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL4KSdQnSqpN3E1kJ4d96VsP4ND-q_VO8vVN1VEiEupYwQyI4wtdWKQl4JPUnAwGIR1DIqofdIe9jynrSdUZeuRoQw9y2fWbztZAPZ5fuyTWJoXSoS5NETNnoQq6JhmSL0VtArLhrmIkqvj_p_4p2jsPtoS04XFe1wR7dl9IC3t0VAEGl6gb9fre6T60A/s320/erlang_logo_icon_169196.png" width="320" /></a></div><br />Una tupla es una forma de organizar datos. Es una forma de agrupar muchos términos cuando sabes cuántos hay. En Erlang, una tupla se escribe en la forma {Elemento1, Elemento2,..., ElementoN}. Como ejemplo, me darías las coordenadas (x,y) si quisieras decirme la posición de un punto en una gráfica cartesiana. Podemos representar este punto como una tupla de dos términos:<p></p><p>1> X = 10, Y = 4.</p><p>4</p><p>2> Point = {X,Y}.</p><p>{10,4}</p><p><br /></p><p>En este caso, un punto siempre serán dos términos. En lugar de llevar las variables X e Y por todos lados, solo tienes que llevar una. Sin embargo, ¿qué puedo hacer si recibo un punto y sólo quiero la coordenada X? No es difícil extraer esa información. Recuerde que cuando asignamos valores, Erlang nunca se quejaría si fueran iguales. </p><p>3> Point = {4,5}.</p><p>{4,5}</p><p>4> {X,Y} = Point.</p><p>{4,5}</p><p>5> X.</p><p>4</p><p>6> {X,_} = Point.</p><p>{4,5}</p><p><br /></p><p>Ahora podemos usar X con el valor. Primero, X e Y no tenían valor y, por lo tanto, se consideraban variables independientes. Cuando los configuramos en la tupla {X,Y} en el lado izquierdo del operador =, el operador = compara ambos valores: {X,Y} vs. {4,5}. Erlang es lo suficientemente inteligente como para descomprimir los valores de la tupla y distribuirlos a las variables independientes en el lado izquierdo. Entonces la comparación es solo {4,5} = {4,5}, ¡lo cual obviamente tiene éxito! Esa es una de las muchas formas de coincidencia de patrones.</p><p>En la expresión 6, se utilizo la variable _ anónima y se usa cuando no queremos ese valor. La variable _ siempre se considera independiente y actúa como comodín para la coincidencia de patrones. La coincidencia de patrones para descomprimir tuplas solo funcionará si el número de elementos (la longitud de la tupla) es el mismo.</p><p><br /></p><p>7> {_,_} = {4,5}.</p><p>{4,5}</p><p>8> {_,_} = {4,5,6}.</p><p>** exception error: no match of right hand side value {4,5,6}</p><p><br /></p><p>Las tuplas también pueden resultar útiles cuando se trabaja con valores únicos. ¿Cómo es eso? El ejemplo más simple es la temperatura:</p><p><br /></p><p>9> Temperature = 23.213.</p><p>23.213</p><p>Bueno, parece un buen día para ir a la playa... Espera, ¿esta temperatura está en Kelvin, Celsius o Fahrenheit?</p><p><br /></p><p>10> PreciseTemperature = {celsius, 23.213}.</p><p>{celsius,23.213}</p><p>11> {kelvin, T} = PreciseTemperature.</p><p>** exception error: no match of right hand side value {celsius,23.213}</p><p><br /></p><p>Esto arroja un error, ¡pero es exactamente lo que queremos! Esto es, nuevamente, coincidencia de patrones en acción. El operador = termina comparando {kelvin, T} y {celsius, 23.213}: incluso si la variable T no está unida, Erlang no verá el átomo celsius como idéntico al átomo kelvin al compararlos. Se lanza una excepción que detiene la ejecución del código. Al hacerlo, la parte de nuestro programa que espera una temperatura en Kelvin no podrá procesar las temperaturas enviadas en Celsius. Esto hace que sea más fácil para el programador saber qué se envía y también funciona como ayuda de depuración. Una tupla que contiene un átomo seguido de un elemento se denomina "tupla etiquetada". Cualquier elemento de una tupla puede ser de cualquier tipo, incluso de otra tupla:</p><p><br /></p><p>12> {point, {X,Y}}.</p><p>{point,{4,5}}</p><p><br /></p>emanuelpeghttp://www.blogger.com/profile/04711040685976318775noreply@blogger.com0