This is a great demo of R Type Provider presented by Howard Mansell in September 2012.
Look at this, if you missed it as I did. It is really exciting!
Father. Husband. Developer. Microsoft MVP. Likes #fsharp 🦔, #rust 🦀 and OSS.
This is a great demo of R Type Provider presented by Howard Mansell in September 2012.
Look at this, if you missed it as I did. It is really exciting!
– “What can C# do that F# cannot?”
-“NullReferenceException :-)”
Tomas Petricek.
Welcome to F# Weekly,
Using this weekly, I would like to introduce Nando de Freitas for everyone who interested in machine learning. He is a machine learning professor at UBC. He has an excellent YouTube channel with lots of interesting lectures. Follow him if you are interested.
A roundup of F# content from this past week:
News
Videos
Blogs
That’s all for now. Have a great week.
Previous F# Weekly edition – #11

“To be, or not to be”
William Shakespeare
Why people choose F#? This is actually an interesting question. Everyone, who does not use it yet, should find a reason that will force him to try F# or even start use it in production. New posts like ‘Why F#’ have begun to appear more often. It is a good time to collect all thoughts in one post and give a way to think about F# one more time.
The latest thoughts about F#:
Pay attention to the publishing date – things might have changed.
A little bit earlier thoughts:
Some discussions:
If you still do not use F#, it is a good time to read stories from the others and think one more time.
P.S. If you know any other interesting posts/discussions about why people like or dislike F#, please, leave a link in comments. Thanks.
There is an excellent Venn Diagram that describes a real sense of Data Science (by Drew Conway). Read more.
Welcome to F# Weekly,
One more week passed by with an excellent event “Functional Programming Exchange 2013“. All tracks are recorded and available on the conference page. But this is not the only event in F# universe, so see details below:
News
Videos
Blogs
That’s all for now. Have a great week.
Previous F# Weekly edition – #10
I have found that I have a large set of interesting and maybe sometimes useful applications. I have been programming for 14 years, I started from Pascal and tried Delphi, C++, Java, Perl, Clipper, FoxPro, Lua , JavaScript, C#, Octave, Python, Scala, R, F# (and may be something else that I currently do not remember). Through the years I created set of programs that may be interesting for someone else. These programs may look simple for experts, but I hope that they can be useful for beginners. So, I would like to add a new rubric to my blog, called “Apps”, where I will try to collect and share as much as I can find)
This post is about second version of the small maze game that called SuperSDG2, which was created in 2005 using C++, OpenGL(glut32) and a bit of passion. In the game, you are a lonely red ball in the large terrible maze. Your only wish is to find an exit from the random-generated maze. It is strange, but exit is a yellow ball ;). The source code and binaries of this application are available on GitHub.
Control keys:
Feel free to download binaries, play and modify the source code.
/********************************
* SuperSDG v2.2 release
* Copyright (c) 2002-2008 Ravent
* All rights reserved
*********************************/
#pragma comment (lib,"glut32.lib")
#pragma comment (lib,"glaux.lib")
#include "glaux.h"
#include "glut.h"
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define _USE_MATH_DEFINES
#include <math.h>
#include <time.h>
const int sMax=6, m=40, mm=m+1, direction_parts=36;
int cur_direction=0;
double distance=4.;
unsigned textureId = -1, texFloor = -1;
AUX_RGBImageRec *localTexture = NULL, *localFloor = NULL;
int glWin,pathLen,myLen=0;
struct Tpos
{char x,y;};
struct Player
{
int x,y,z;
int dx,dz;
bool isGo;
}player,ex;
struct Maps
{int x,z;} map;
char data[m+2][m+2], cp[m+2][m+2];
float lightAmb [] = { 0.03, 0.03, 0.03 };
float lightDif [] = { 0.95, 0.95, 0.95 };
float lightPos [] = { (int)m/2, 7, (int)m/2 };
void display(void);
void halt(bool f=false);
void drawFloor(GLfloat x1, GLfloat x2, GLfloat z1, GLfloat z2, unsigned texture=texFloor)
{
glBindTexture ( GL_TEXTURE_2D, texture );
glBegin(GL_POLYGON);
glNormal3f( 0.0, 1.0, 0.0);
glTexCoord2f(0,0);
glVertex3f( x1, 0, z2 );
glTexCoord2f(1,0);
glVertex3f( x2, 0, z2 );
glTexCoord2f(1,1);
glVertex3f( x2, 0, z1 );
glTexCoord2f(0,1);
glVertex3f( x1, 0, z1 );
glEnd();
}
void drawBox (GLint j, GLint i, unsigned texture=textureId)
{
GLfloat x1=i, x2=i+1, y1=0, y2=1, z1=j, z2=j+1;
glBindTexture ( GL_TEXTURE_2D, texture );
if ((j==map.z+1)||(data[j-1][i]!='x'))
{
glBegin(GL_POLYGON); // Back
glNormal3f( 0.0, 0.0, -1.0);
glTexCoord2f(0,0);
glVertex3f( x2, y1, z1 );
glTexCoord2f(1,0);
glVertex3f( x1, y1, z1 );
glTexCoord2f(1,1);
glVertex3f( x1, y2, z1 );
glTexCoord2f(0,1);
glVertex3f( x2, y2, z1 );
glEnd();
}
if ((j==map.z-1)||(data[j+1][i]!='x'))
{
glBegin(GL_POLYGON); // Front
glNormal3f( 0.0, 0.0, 1.0);
glTexCoord2f(0,0);
glVertex3f( x1, y1, z2 );
glTexCoord2f(1,0);
glVertex3f( x2, y1, z2 );
glTexCoord2f(1,1);
glVertex3f( x2, y2, z2 );
glTexCoord2f(0,1);
glVertex3f( x1, y2, z2 );
glEnd();
}
if ((i>0)&&(data[j][i-1]!='x'))
{
glBegin(GL_POLYGON); // Left
glNormal3f( -1.0, 0.0, 0.0);
glTexCoord2f(0,0);
glVertex3f( x1, y1, z1 );
glTexCoord2f(1,0);
glVertex3f( x1, y1, z2 );
glTexCoord2f(1,1);
glVertex3f( x1, y2, z2 );
glTexCoord2f(0,1);
glVertex3f( x1, y2, z1 );
glEnd();
}
if ((i<map.x)&&(data[j][i+1]!='x'))
{
glBegin(GL_POLYGON); // Right
glNormal3f( 1.0, 0.0, 0.0);
glTexCoord2f(0,0);
glVertex3f( x2, y1, z2 );
glTexCoord2f(1,0);
glVertex3f( x2, y1, z1 );
glTexCoord2f(1,1);
glVertex3f( x2, y2, z1 );
glTexCoord2f(0,1);
glVertex3f( x2, y2, z2 );
glEnd();
}
glBegin(GL_POLYGON); // Top
glNormal3f( 0.0, 1.0, 0.0);
glTexCoord2f(0,0);
glVertex3f( x1, y2, z2 );
glTexCoord2f(1,0);
glVertex3f( x2, y2, z2 );
glTexCoord2f(1,1);
glVertex3f( x2, y2, z1 );
glTexCoord2f(0,1);
glVertex3f( x1, y2, z1 );
glEnd();
}
void animate()
{
if ((player.x == ex.x)&&(player.z==ex.z))
{
halt(true);
};
if (player.isGo==true)
{
if (player.dx>0) player.dx+=1; else
if (player.dz>0) player.dz+=1; else
if (player.dx<0) player.dx-=1; else
if (player.dz<0) player.dz-=1;
if ((player.dx>=sMax)||(player.dz>=sMax))
{
player.isGo=false;
if (player.dx>0) player.x+=1;
if (player.dz>0) player.z+=1;
player.dx=0; player.dz=0;
}else
if ((player.dx<=-sMax)||(player.dz<=-sMax))
{
player.isGo=false;
if (player.dx<0) player.x-=1;
if (player.dz<0) player.z-=1;
player.dx=0; player.dz=0;
}
}
glutPostRedisplay();
}
void init()
{
glClearColor( 0.0, 0.0, 0.0, 1.0 );
glEnable( GL_DEPTH_TEST );
glEnable( GL_TEXTURE_2D );
glEnable( GL_CULL_FACE );
glPixelStorei ( GL_PACK_ALIGNMENT, 1 );
glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 );
glShadeModel (GL_SMOOTH);
glLightfv ( GL_LIGHT0, GL_AMBIENT, lightAmb );
glLightfv ( GL_LIGHT0, GL_DIFFUSE, lightDif );
//glLightfv ( GL_LIGHT0, GL_POSITION, lightPos );
glEnable ( GL_LIGHT0 );
glEnable ( GL_LIGHTING );
player.dx=0; player.dz=0; player.isGo=false;
glEnable(GL_COLOR_MATERIAL);
}
void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
gluLookAt(player.x+(1.0*player.dx/sMax)+0.5f+3*cos(M_PI_2+cur_direction/double(direction_parts)*2.*M_PI),player.y+distance,player.z+(1.0*player.dz/sMax)+0.5f+3*sin(M_PI_2+cur_direction/double(direction_parts)*2.*M_PI),
player.x+(1.0*player.dx/sMax)+0.5f,player.y+0.5f,player.z+(1.0*player.dz/sMax)+0.5f,
0,1,0);
for (int i=0;i<map.x;i++)
for (int j=0;j<map.z;j++)
if (data[j][i] == 'x')
{
drawBox(j,i);
} else {
drawFloor(i,i+1,j,j+1);
}
glPushMatrix();
glTranslatef ( player.x+(1.0*player.dx/sMax)+0.5f, player.y+0.5f, player.z+(1.0*player.dz/sMax)+0.5f);
glColor3d(1,0,0);
glutSolidSphere(0.5,100,100);
glColor3d(1,1,1);
glPopMatrix();
glPushMatrix();
glTranslatef ( ex.x +0.5f, ex.y+0.5f, ex.z+0.5f);
glColor4d(1,1,0.,0.4);
glutSolidSphere(0.5,100,100);
glColor3d(1,1,1);
glPopMatrix();
glutSwapBuffers();
}
void reshape ( int w, int h )
{
glViewport( 0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 60.0, (GLfloat)w/(GLfloat)h, 1.0, 60.0);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
gluLookAt(0,0,25,0,0,0,0,1,0);
}
void key( unsigned char key, int x, int y)
{
if ( key=='q' || key=='Q' || key == 27) halt(false);
if ( key=='a' || key=='A' ) { cur_direction--; if (cur_direction<0) cur_direction+=direction_parts;}
if ( key=='s' || key=='S' ) { cur_direction++; if (cur_direction==direction_parts) cur_direction=0;}
if ((key=='z' || key=='Z') && (distance<58.) ) distance+=0.25;
if ((key=='x' || key=='X') && (distance>3.) ) distance-=0.25;
if ( key=='r' || key=='R' ) { cur_direction=0; distance=4.;}
}
const int move[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
const int move_key[4] = {GLUT_KEY_UP, GLUT_KEY_LEFT, GLUT_KEY_DOWN, GLUT_KEY_RIGHT };
bool good_move(int z, int x){
return (0<=z && 0<=x && z<map.z && x<map.x && data[z][x]!='x');
}
void keys( int key, int x, int y)
{
if (player.isGo) return;
int dir=int(((direction_parts-cur_direction-1)/double(direction_parts))*4.+0.5);
for (int i=0; i<4; i++)
if ( key == move_key[i] ) {
int newz=player.z+move[(dir+i)%4][0];
int newx=player.x+move[(dir+i)%4][1];
if (good_move(newz,newx)) {
player.isGo=true;
player.dz+=move[(dir+i)%4][0];
player.dx+=move[(dir+i)%4][1];
myLen++;
}
}
}
void genMap(void);
int main (int argc, char** argv)
{
genMap();
glutInit(&argc,argv);
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
glutInitWindowSize(1024,768);
glWin = glutCreateWindow("SuperSDG 2");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(key);
glutSpecialFunc(keys);
glutIdleFunc(animate);
localTexture = auxDIBImageLoad(L"1.bmp");
glGenTextures (1,&textureId);
glBindTexture (GL_TEXTURE_2D,textureId);
glPixelStorei (GL_UNPACK_ALIGNMENT,1);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);
gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, localTexture->sizeX, localTexture->sizeY, GL_RGB, GL_UNSIGNED_BYTE, localTexture->data);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
localFloor = auxDIBImageLoad(L"2.bmp");
glGenTextures (1,&texFloor);
glBindTexture (GL_TEXTURE_2D,texFloor);
glPixelStorei (GL_UNPACK_ALIGNMENT,1);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);
gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, localFloor->sizeX, localFloor->sizeY, GL_RGB, GL_UNSIGNED_BYTE, localFloor->data);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glutFullScreen();
glutMainLoop();
return 0;
}
int step(int y, int x)
{
int res=0;
if ((data[y][x]=='x')) res++;
if ((y<mm)&&(data[y+1][x]=='x')) res++;
if ((y>0 )&&(data[y-1][x]=='x')) res++;
if ((x<mm)&&(data[y][x+1]=='x')) res++;
if ((x>0 )&&(data[y][x-1]=='x')) res++;
return res;
}
int stepC(int y, int x)
{
int res=0;
if ((cp[y][x]=='x')) res++;
if ((y<mm)&&(cp[y+1][x]=='x')) res++;
if ((y>0 )&&(cp[y-1][x]=='x')) res++;
if ((x<mm)&&(cp[y][x+1]=='x')) res++;
if ((x>0 )&&(cp[y][x-1]=='x')) res++;
return res;
}
void DataToCp(void)
{
for(int j=1;j<=mm;j++)
for (int i=1;i<=mm;i++)
cp[j][i]=data[j][i];
}
void fill (int y,int x,Tpos *v, int *l)
{
int st=1,en=0;
int G[mm*mm],Ll[mm*mm];
G[0]=y*mm+x; Ll[0]=0;
cp[y][x]='x';
while (st!=en)
{
if ((G[en]%mm+1<mm)&&(cp[(int)G[en]/mm][G[en]%mm+1]=='.'))
{
G[st]=G[en]+1;
Ll[st]=Ll[en]+1;
cp[(int)G[st]/mm][G[st]%mm]='x';
st++;
}
if ((G[en]%mm-1>0)&&(cp[(int)G[en]/mm][G[en]%mm-1]=='.'))
{
G[st]=G[en]-1;
Ll[st]=Ll[en]+1;
cp[(int)G[st]/mm][G[st]%mm]='x';
st++;
}
if ((((int)G[en]/mm)+1<mm)&&(cp[((int)G[en]/mm)+1][G[en]%mm]=='.'))
{
G[st]=G[en]+mm;
Ll[st]=Ll[en]+1;
cp[(int)G[st]/mm][G[st]%mm]='x';
st++;
}
if ((((int)G[en]/mm)-1>0)&&(cp[((int)G[en]/mm)-1][G[en]%mm]=='.'))
{
G[st]=G[en]-mm;
Ll[st]=Ll[en]+1;
cp[(int)G[st]/mm][G[st]%mm]='x';
st++;
}
en++;
}
int rnd=rand()%5+1;
(*v).x =(int) G[en-rnd] % mm;
(*v).y =(int) G[en-rnd] / mm;
*l=Ll[en-rnd];
}
bool isGood(Tpos a)
{
DataToCp();
int k=0,i,j,lt;
Tpos temp;
cp[a.y][a.x]='x';
if ((step(a.y,a.x)>3)||(step(a.y+1,a.x)>3)||(step(a.y-1,a.x)>3)||(step(a.y,a.x+1)>3)||(step(a.y,a.x-1)>3))
return false;
for(j=1;j<=m;j++)
for(i=1;i<=m;i++)
if (cp[j][i]=='.')
{
if (k>0)
return false;
fill(j,i,&temp,<);
k++;
}
return true;
}
void genMap()
{
int i,j;
map.x=m+2; map.z=m+2;
printf("Loading... Please Wait.\n");
srand( (unsigned)time( NULL ) );
for (j=0;j<map.z;j++)
for (i=0;i<map.x;i++)
{
if ((i==0)||(j==0)||(i==map.x-1)||(j==map.z-1))
data[j][i]='x';
else
data[j][i]='.';
}
int k=0;
Tpos t;
while (k<(int)m*m/2.5)
{
t.x = rand()%mm+1;
t.y = rand()%mm+1;
if ((data[t.y][t.x]=='.')&&(isGood(t)))
{
data[t.y][t.x]='x';
k++;
}
}
for (j=1;j<=m;j++)
for (i=1;i<=m;i++)
if ((data[j][i]=='x')&&(step(j,i)>3))
{
data[j][i]='.';
}
for (j=1;j<=m;j++)
for (i=1;i<=m;i++)
if ((data[j][i]=='.')&&(step(j,i)<2))
{
t.x = i; t.y=j;
if (isGood(t))
data[j][i]='x';
}
Tpos ps[11]; k=0;
while (k<=10)
{
t.x = rand()%mm+1;
t.y = rand()%mm+1;
if (data[t.y][t.x]=='.')
{
ps[k]=t;
k++;
}
}
k=rand()%11;
player.x=ps[k].x;
player.z=ps[k].y;
DataToCp();
fill(ps[k].y,ps[k].x,&t,&pathLen);
ex.x=t.x;
ex.z=t.y;
printf("Loading complete.\n");
}
void halt(bool f)
{
glutDestroyWindow(glWin);
printf("-----------------------------------------------------\n");
printf("# SuperSDG 2.2 #\n");
if (f==true)
{
printf("-----------------------------------------------------\n");
printf("# The shortest path %d. #\n",pathLen);
printf("# Your path %d. #\n",myLen);
printf("# Congratulate you passed the game. #\n");
if ( 1.2*pathLen >= myLen )
{
printf("-----------------------------------------------------\n");
printf("# YOU ONE OF THE BEST PLAYER OF THE WORLD. #\n");
}
}
printf("-----------------------------------------------------\n");
printf("# Developers: #\n");
printf("# Ravent - programmer. #\n");
printf("# Series found: #\n");
printf("# Ravent - Sergey Tihon #\n");
printf("# MasterZerg - Dima Rudol #\n");
printf("-----------------------------------------------------\n");
printf("# Copyright (c) Ravent 2002-2008. #\n");
printf("# All rights reserved #\n");
printf("-----------------------------------------------------\n");
getch();
exit(0);
}
XNA Game Studio is one of the main pure managed 3D data visualization tools. It is widely used for game development and operates not only on PC but on Xbox and Windows Phones too.
As you probably know, The F# Software Foundation has a “Game And Visualization Stacks” page with description of options available from F#. On this page you can find a link to the “F# With XNA Game Studio” post by AzerDark (@azer89). In the post you can find the detailed guide of how to create a new F# project, reference all required assemblies and create minimal XNA application that shows up an empty window.
I have tried to create something a bit more interesting than an empty window. It is a rotating cube :). A full description of how it works you can find in the post “Getting started with 3D XNA” by David Conrad (with source code in C#). In this post you can see F# code that create XNA game object and model of cube, initialize basic effect (turn on light and configure light, projection and view), create an animation(rotating) for cube and render it in XNA window. As a result, you will see something like that (but with animation 😉 ):
open System
open Microsoft.Xna.Framework
open Microsoft.Xna.Framework.Graphics
open Microsoft.Xna.Framework.Input
type Game1() as this =
inherit Game()
let graphics = new GraphicsDeviceManager(this)
let cube =
let texCoords = new Vector2(0.0f, 0.0f);
let face = [|Vector3(-1.0f, 1.0f, 0.0f); Vector3(-1.0f, -1.0f, 0.0f);
Vector3(1.0f, 1.0f, 0.0f); //TopLeft-BottomLeft-TopRight
Vector3(-1.0f, -1.0f, 0.0f); Vector3(1.0f, -1.0f, 0.0f);
Vector3(1.0f, 1.0f, 0.0f);|] //BottomLeft-BottomRight-TopRight
let faceNormals = [|Vector3.UnitZ; -Vector3.UnitZ; //Front & Back faces
Vector3.UnitX; -Vector3.UnitX; //Left & Right faces
Vector3.UnitY; -Vector3.UnitY|]; //Top & Bottom faces
let ang90 = (float32)Math.PI / 2.0f;
let faceRotations = [|Matrix.CreateRotationY(2.0f*ang90); Matrix.CreateRotationY(0.0f);
Matrix.CreateRotationY(-ang90); Matrix.CreateRotationY(ang90);
Matrix.CreateRotationX(ang90); Matrix.CreateRotationX(-ang90)|];
Array.init 36 (fun x ->
let i,j = x%6, x/6
VertexPositionNormalTexture(
Vector3.Transform(face.[i], faceRotations.[j])
+ faceNormals.[j], faceNormals.[j], texCoords))
let mutable effect = null
let angle = ref 0.0f;
override Game.Initialize() =
effect <- new BasicEffect(graphics.GraphicsDevice,
AmbientLightColor = Vector3(0.0f, 1.0f, 0.0f),
LightingEnabled = true,
View = Matrix.CreateTranslation(0.0f,0.0f,-10.0f),
Projection =
Matrix.CreatePerspectiveFieldOfView(
(float32)Math.PI / 4.0f,
(float32)this.Window.ClientBounds.Width
/ (float32)this.Window.ClientBounds.Height,
1.0f, 10.0f));
effect.DirectionalLight0.Enabled <- true;
effect.DirectionalLight0.DiffuseColor <- Vector3.One;
effect.DirectionalLight0.Direction <- Vector3.Normalize(Vector3.One);
base.Initialize()
override Game.Update gameTime =
angle := !angle + 0.005f
if (!angle > 2.0f * (float32)Math.PI) then angle := 0.0f;
let R = Matrix.CreateRotationY(!angle) * Matrix.CreateRotationX(0.4f);
let T = Matrix.CreateTranslation(0.0f, 0.0f, 5.0f);
effect.World <- R * T;
base.Update gameTime
override Game.Draw gameTime =
this.GraphicsDevice.Clear(Color.CornflowerBlue)
graphics.GraphicsDevice.RasterizerState <- new RasterizerState();
effect.CurrentTechnique.Passes |> Seq.iter (fun pass ->
pass.Apply()
graphics.GraphicsDevice.DrawUserPrimitives(
PrimitiveType.TriangleList, cube, 0, 12))
base.Draw gameTime
[<EntryPoint>]
let main argv =
use g = new Game1()
g.Run()
0
According to the sad situation in nowadays front-end development, we have to check current browser type and version in JavaScript code and behave differently depend on that. There are many options to do so like this or this. But working in SharePoint 2010 environment you have one more, init.js defines browseris object (see on the picture below) which contains most of required data. Be free to rely on SharePoint in this case.
